在Java中,哪个是最好的XML解析库?

174

我正在搜索用于解析XML(复杂配置和数据文件)的Java库,我在谷歌上搜了一下,但除了dom4j(似乎他们正在开发V2)之外没有找到其他内容。我看过commons-configuration,但不喜欢它,其他关于XML的Apache项目似乎都已经停滞不前了。我还没有自己评估过dom4j,只是想知道 - Java是否有其他(好的)开源XML解析库?你使用dom4j的体验如何?

在@Voo的回答后,让我再问一个问题 - 我应该使用Java的内置类还是像dom4j这样的第三方库..有什么优点?


你能定义什么是好的吗?性能、API质量还是其他什么? - Yishai
性能和易用性(是的,API质量) - Premraj
4
你并没有说明不使用Java原生实现的具体原因。 - Hovercraft Full Of Eels
vtd-xml 将成为性能/内存使用和易用性方面的佼佼者。 - vtd-xml-author
你也可以查看 jcabi-xm(我是开发者) - yegor256
7个回答

232

实际上,Java内置了4种解析XML的方法:

DOM解析器/构建器:将整个XML结构加载到内存中,并可以使用众所周知的DOM方法进行操作。DOM还允许您使用XSLT转换向文档中写入内容。 示例:

public static void parse() throws ParserConfigurationException, IOException, SAXException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setIgnoringElementContentWhitespace(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    File file = new File("test.xml");
    Document doc = builder.parse(file);
    // Do something with the document here.
}

SAX解析器:仅用于读取XML文档。Sax解析器遍历文档并调用用户的回调方法。有关文档、元素等的开始/结束方法已在org.xml.sax.ContentHandler中定义,还有一个空的助手类DefaultHandler。

public static void parse() throws ParserConfigurationException, SAXException {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setValidating(true);
    SAXParser saxParser = factory.newSAXParser();
    File file = new File("test.xml");
    saxParser.parse(file, new ElementHandler());    // specify handler
}

StAx读写器:这个工具使用基于数据流的接口工作。程序会在准备好时请求下一个元素,就像光标/迭代器一样。您也可以使用它创建文档。

阅读文档:

public static void parse() throws XMLStreamException, IOException {
    try (FileInputStream fis = new FileInputStream("test.xml")) {
        XMLInputFactory xmlInFact = XMLInputFactory.newInstance();
        XMLStreamReader reader = xmlInFact.createXMLStreamReader(fis);
        while(reader.hasNext()) {
            reader.next(); // do something here
        }
    }
}

编写文档:

public static void parse() throws XMLStreamException, IOException {
    try (FileOutputStream fos = new FileOutputStream("test.xml")){
        XMLOutputFactory xmlOutFact = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = xmlOutFact.createXMLStreamWriter(fos);
        writer.writeStartDocument();
        writer.writeStartElement("test");
        // write stuff
        writer.writeEndElement();
    }
}

JAXB:最新的实现可以读取XML文档:在Java 6中的v2版本中提供。这使我们能够从文档序列化Java对象。您可以使用实现javax.xml.bind.Unmarshaller接口的类来读取文档(您可以从JAXBContext.newInstance获得此类)。上下文必须使用所使用的类进行初始化,但您只需指定根类即可,不必担心静态引用的类。 您可以使用注释来指定哪些类应该是元素(@XmlRootElement),哪些字段是元素(@XmlElement)或属性(@XmlAttribute,真是个惊喜!)

public static void parse() throws JAXBException, IOException {
    try (FileInputStream adrFile = new FileInputStream("test")) {
        JAXBContext ctx = JAXBContext.newInstance(RootElementClass.class);
        Unmarshaller um = ctx.createUnmarshaller();
        RootElementClass rootElement = (RootElementClass) um.unmarshal(adrFile);
    }
}

编写文档:

public static void parse(RootElementClass out) throws IOException, JAXBException {
    try (FileOutputStream adrFile = new FileOutputStream("test.xml")) {
        JAXBContext ctx = JAXBContext.newInstance(RootElementClass.class);
        Marshaller ma = ctx.createMarshaller();
        ma.marshal(out, adrFile);
    }
}

这些例子是从一些老的讲义干脆地复制而来的 ;-)

关于“我应该使用哪个API?”。好吧,这取决于情况 - 并非所有API都具有相同的功能,但如果您可以控制用于映射XML文档的类,则JAXB是我个人最喜欢的选择,非常优雅和简单(虽然我没有用它处理过真正大的文档,可能会变得有点复杂)。SAX也很容易使用,如果您没有真正好的理由使用DOM,请远离它 - 在我看来,这是一个旧的、笨重的API。我认为没有任何现代的第三方库提供特别有用的功能,这些功能在STL中缺失,标准库具有通常的优势,即经过极其充分的测试、文档化和稳定。


@Natix这就是“编辑”选项的作用。现在应该更好了。 - Kikiwa
4
异常处理与这篇文章的重点几乎没有关系。如果一些不称职的复制粘贴程序员在不理解代码目的的情况下复制代码片段,那么他们会得到他们应得的结果。我并不担心或对他们感兴趣。我要说的是,删除try/catch块并显示方法签名来记录不同选项可能抛出的异常,可以节省空间,同时保留有趣的信息。因此,如果有人想这样做,他们应该直接去做。 - Voo
1
同时,如果编辑没有用其他方式注明了附加信息,我将拒绝删除try/catch。 - Voo
我相信在最近的JDK版本中已经不再包含JAXB。 - Slaw

12

Java提供了两种内置的XML解析方法。

SAXParser

如果你想解析大型XML文件和/或不想使用太多内存,可以使用此解析器。

http://download.oracle.com/javase/6/docs/api/javax/xml/parsers/SAXParserFactory.html

示例:http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

DOMParser

如果你需要执行XPath查询或需要完整的DOM,则可以使用此解析器。

http://download.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html

示例:http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/


9
如果你需要一个类似于DOM的API——也就是说,一个XML解析器将文档转换为元素和属性节点的树形结构,那么至少有四个选择:DOM本身、JDOM、DOM4J和XOM。唯一可能使用DOM的原因是它被视为标准并且在JDK中提供:在其他方面,其他的都更优秀。针对简洁性、功能性以及性能综合考虑,我个人偏好XOM。
当然,还有其他风格的处理方式:低级解析器接口(SAX和StAX)、数据对象绑定接口(JAXB)和高级声明语言(XSLT、XQuery、XPath)。哪种最适合你取决于你的项目要求和个人喜好。

2
DOM是W3C标准(http://www.w3.org/DOM/)的一部分。该标准的Java实现由JAXP标准(http://jcp.org/en/jsr/detail?id=206)覆盖。然后,JAXP由不同的提供商实现,例如:Oracle、Apache等。 - bdoughan
事实上,如果没有以下两个原因,没有人会使用DOM:(a)它被定义为标准并且有多个实现,(b)它默认包含在JDK中。从所有其他角度来看,JDOM2和XOM更可取。 - Michael Kay

4
尼基塔的观点非常好:不要把成熟与不好混淆。XML 没有改变太多。
JDOM 可以作为 DOM4J 的另一种选择。

你会选择哪一个,为什么? - Premraj
1
这并不是很重要。两者都是 JDK 内置的 SAX 和 DOM 解析器的包装器。W3C 文档层次结构冗长且难以使用,因此 DOM4J 和 JDOM 都试图使其更易于使用。我喜欢 Elliott Rusty Harold,所以我倾向于首选 JDOM。 - duffymo

4

在Java中,您不需要外部库来解析XML。自古以来,Java就带有内置的SAX和DOM实现。


3

0

3
警告:VTD-XML采用GPL许可证,这使得它在绝大多数专业或商业开发环境下都不适用。工程师应咨询自己的律师进行分析,但如果您从事的是工程师工作并且获得报酬,那么您极有可能会发现您所在的组织不允许(也无法)使用任何采用GPL许可证的库。 - Sarah G
那个链接已经失效了。 - null

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