如何计算元素节点

时间:2015-07-10 09:03:27

标签: java xml dom xpath sax

我在下面发布了一个XML文件,我想要的是使用xpath计算所有元素,其中XML节点名为“node”。我写了下面的代码,我希望得到结果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"/>

1 个答案:

答案 0 :(得分: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);