2015-07-10 4 views
1

Я разместил XML-файл ниже, и я хочу, чтобы подсчитать все элементы, где узел XML называется «узлом», используя xpath. Я написал следующий код, и я ожидал получить результат 9, так как существует 9 элементов узла, называемых «узлом», но результат, который я получаю, отличается и показан ниже. Не могли бы вы помочь?Как подсчитать узлы элементов

Результаты:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
at com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase.ensureSizeOfIndex(Unknown Source) 
at com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase.indexNode(Unknown Source) 
at com.sun.org.apache.xml.internal.dtm.ref.dom2dtm.DOM2DTM.addNode(Unknown Source) 
at com.sun.org.apache.xml.internal.dtm.ref.dom2dtm.DOM2DTM.nextNode(Unknown Source) 
at com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBaseTraversers$IndexedDTMAxisTraverser.getNextIndexed(Unknown Source) 
at com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBaseTraversers$DescendantTraverser.next(Unknown Source) 
at com.sun.org.apache.xpath.internal.axes.DescendantIterator.nextNode(Unknown Source) 
at com.sun.org.apache.xpath.internal.axes.LocPathIterator.getLength(Unknown Source) 
at com.sun.org.apache.xpath.internal.axes.NodeSequence.getLength(Unknown Source) 
at com.sun.org.apache.xpath.internal.functions.FuncCount.execute(Unknown Source) 
at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source) 
at com.sun.org.apache.xpath.internal.XPath.execute(Unknown Source) 
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(Unknown Source) 
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source) 
at com.example.xpath_01.MainClass.main(MainClass.java:40) 

код:

Document document = builder.parse(new FileInputStream("c:\\bremen.xml")); 
XPathFactory xpathFactory = XPathFactory.newInstance(); 
XPath xPath = xpathFactory.newXPath(); 

String expr0 = "count(//node)"; 
xPath.compile(expr0); 
String s = (String) xPath.evaluate(expr0, document, XPathConstants.NODE); 

System.out.println(s); 

XML:

<?xml version='1.0' encoding='utf-8' ?> 
<osm> 
<node id="125799" lat="53.0749415" lon="8.7868047"/> 
<node id="125800" lat="53.071932" lon="8.7840591"/> 
<node id="125801" lat="53.0705997" lon="8.7818627"> 
<node id="125802" lat="53.067967" lon="8.7789767"/> 
<node id="125803" lat="53.066404" lon="8.7776205"/> 
<node id="125805" lat="53.0655804" lon="8.7768297"/> 
<node id="125806" lat="53.0633485" lon="8.7743991"/> 
<node id="125807" lat="53.0623592" lon="8.7728449"/> 
<node id="125808" lat="53.0614152" lon="8.7701245"/> 
+0

Double s = (Двухместный) xPath.evaluate (expr0, document, XPathConstants.NUMBER); –

+0

@Mr_Thorynque, когда я использовал XPathConstants.NUMBER, работает только тогда, когда я указываю String expr0 = "count (osm // node)"; и если я просто использовал String expr0 = "count (// node)"; это дает мне ошибку ... может у, пожалуйста, скажите мне, почему? – user2121

+1

Я не знаю, может быть, «узел» - это ключевое слово, а интерпретатор xpaht переходит в цикл infiny ... –

ответ

1

Вы получаете OutOfMemoryError. это означает, что xml-файл является большим для размещения в памяти.

Таким образом, вместо того, чтобы использовать DOM и XPath, использование SAX, как показано ниже:

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

import javax.xml.parsers.SAXParserFactory; 
import java.io.File; 

/** 
* @author Santhosh Kumar Tekuri 
*/ 
public class NodeCountingHandler extends DefaultHandler{ 
    private int count = 0; 

    @Override 
    public void startDocument() throws SAXException{ 
     count = 0; 
    } 

    @Override 
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{ 
     if(localName.equals("node")) 
      ++count; 
    } 

    public static int getNodeCount(File file) throws Exception{ 
     SAXParserFactory factory = SAXParserFactory.newInstance(); 
     factory.setNamespaceAware(true); 
     NodeCountingHandler handler = new NodeCountingHandler(); 
     factory.newSAXParser().parse(file, handler); 
     return handler.count; 
    } 
} 

Теперь, чтобы получить количество узлов, просто сделать:

int nodeCount = NodeCountingHandler.getNodeCount(file); 
+0

но могу ли я использовать xpath с sax ?? Я думал, что xpath можно использовать только в сочетании с dom – user2121

+1

, если вам интересно использовать xpath с sax, вы можете попробовать http://jlibs.in/xmldog/XMLDog.html. BTW Я являюсь владельцем этого проекта –