在Java中查询XML的最快方法

5
什么是在Java中查询大型XML文件的最快方法?
DOM - xpath:这需要很长时间。
     DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
     docBuilderFactory.setNamespaceAware(true);

     DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
     Document document = docBuilder.parse(new File("test.xml"));

     XPath xpath = XPathFactory.newInstance().newXPath();

     String xPath = "/*/*[@id='ABCD']/*/*";

     XPathExpression expr = xpath.compile(xPath);
     //this line takes lot of time
     NodeList result = (NodeList)expr.evaluate(document, XPathConstants.NODESET);

在代码的最后一行,程序需要40秒才能完成,而没有这一行只需要1秒钟。

SAX:我不知道它是否可以用于查询,在互联网上我只能找到解析的示例。

有哪些其他选项可以使查询更快?我的XML文件大小约为5MB。谢谢。


你尝试过使用StAX或JAXB吗? - davek
最快的XML解析器(已经被反复证明)是vtd-xml(http://vtd-xml.sf.net)。 - vtd-xml-author
5个回答

4
如果您的id属性是xs:ID类型,并且您的文档有一个XML模式,那么您可以使用 Document.getElementById(String)方法。下面我将用一个例子来演示。 XML模式:
<?xml version="1.0" encoding="UTF-8"?>
<schema 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/schema" 
    xmlns:tns="http://www.example.org/schema" 
    elementFormDefault="qualified">

    <element name="foo">
        <complexType>
            <sequence>
                <element ref="tns:bar" maxOccurs="unbounded"/>
            </sequence>
        </complexType>
    </element>

    <element name="bar">
        <complexType>
            <attribute name="id" type="ID"/>
        </complexType>
    </element>

</schema>

XML Input (input.xml)

<?xml version="1.0" encoding="UTF-8"?>
<foo xmlns="http://www.example.org/schema">
    <bar id="ABCD"/>
    <bar id="EFGH"/>
    <bar id="IJK"/>
</foo>

演示

要使一切正常工作,您需要在DocumentBuilderFactory上设置Schema的实例。

import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.parsers.*;
import javax.xml.validation.*;
import org.w3c.dom.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = sf.newSchema(new File("src/forum17250259/schema.xsd"));

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setSchema(schema);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document document = db.parse(new File("src/forum17250259/input.xml"));

        Element result = document.getElementById("EFGH");
        System.out.println(result);
    }

}

1

请查看SAX API,因为它是目前处理XML文档最快且最少占用内存的机制。


sax似乎不支持xpath。 - vtd-xml-author

1

这取决于您想执行的查询类型。

例如,如果您只想通过ID查找节点,然后读取其文本内容,SAX将非常快,但需要编写一些代码来编写SAX处理程序(可能是从this扩展的)。

另一方面,如果您想执行类似“获取foo的第三个祖先节点,其中foo有一个名为bah的子节点”的相当复杂的查询,您基本上必须使用xpath,因为SAX处理程序将过于复杂。


1

您可能需要提到vtd-xml是一款商业产品。 - Thorbjørn Ravn Andersen
Vtd-xml在GPL下获得许可,但也可以商业授权。 - vtd-xml-author

-2

试试Jackson库,它是最快的xml/json解析库之一。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接