在java中,哪一个是XML解析的最佳库

在java中,哪一个是XML解析的最佳库,java,xml,parsing,Java,Xml,Parsing,我正在搜索java库来解析XML(复杂的配置和数据文件),我在Google上搜索了一下,但除了dom4j之外找不到其他文件(似乎他们正在处理V2)。。我看过commons配置,但不喜欢它,XML上的其他apache项目似乎处于休眠状态。我自己还没有评估过dom4j,只是想知道——java还有其他(好的)开源xml解析库吗?您对dom4j的体验如何 在@Voo的回答之后,让我问另一个问题——我应该使用java的内置类还是任何第三方库,比如dom4j。。优点是什么?尼基塔的观点很好:不要把成熟和坏混

我正在搜索java库来解析XML(复杂的配置和数据文件),我在Google上搜索了一下,但除了dom4j之外找不到其他文件(似乎他们正在处理V2)。。我看过commons配置,但不喜欢它,XML上的其他apache项目似乎处于休眠状态。我自己还没有评估过dom4j,只是想知道——java还有其他(好的)开源xml解析库吗?您对dom4j的体验如何


在@Voo的回答之后,让我问另一个问题——我应该使用java的内置类还是任何第三方库,比如dom4j。。优点是什么?

尼基塔的观点很好:不要把成熟和坏混为一谈。XML变化不大


JDOM将是DOM4J的另一种替代方案。

在Java中解析XML不需要外部库。多年来,Java已经为SAX和DOM提供了内置的实现。

Java支持两种开箱即用的XML解析方法

SAXParser

如果要解析大型XML文件和/或不想使用大量内存,可以使用此解析器

例如:

DOMParser

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


示例:

实际上,Java支持4种方法来即时解析XML:

domparser/Builder:整个XML结构被加载到内存中,您可以使用众所周知的DOM方法来处理它。DOM还允许您使用Xslt转换写入文档。 例如:

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();
    }
}
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);
    }
}
编写文档:

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();
    }
}
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);
    }
}
JAXB:读取XML文档的最新实现:是v2中Java6的一部分。这允许我们从文档序列化java对象。阅读文档时使用了一个类,该类实现了javax.xml.bind.Unmarshaller的接口(从JAXBContext.newInstance获得了一个用于此的类)。上下文必须使用使用的类进行初始化,但是您只需要指定根类,而不必担心静态引用类。 您可以使用注释来指定哪些类应该是元素(@XmlRootElement),哪些字段应该是元素(@XmlElement)或属性(@XmlAttribute,真令人惊讶!)

编写文档:

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();
    }
}
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中缺少的任何特别有用的功能,标准库具有经过良好测试、记录和稳定的通常优势。

VTD-XML是一种重型XML解析库。。。事实上,它在各个方面都比别人好。。。这是一篇2013年的论文,分析了java平台上所有可用的XML处理框架


如果您想要一个类似DOM的API,也就是XML解析器将文档转换为元素和属性节点树的API,那么至少有四个可供选择:DOM本身、JDOM、DOM4J和XOM。使用DOM的唯一可能的原因是,它被视为一种标准,并由JDK提供:在所有其他方面,其他方面都优于DOM。我个人的偏好是XOM,因为它结合了简单性、功能和性能


当然,还有其他处理风格:低级解析器接口(SAX和StAX)、数据对象绑定接口(JAXB)和高级声明性语言(XSLT、XQuery、XPath)。哪种方法最适合您取决于您的项目需求和个人喜好。

对于那些对使用JDOM感兴趣但又担心JDOM在一段时间内没有更新(特别是没有利用Java泛型)的人来说,有一种称为CoffeeDOM的fork,它正好解决了这些问题并使JDOM API现代化,请阅读以下内容:

并从项目页面下载,网址为:


你能定义好吗?性能,API的质量,还有其他吗?性能和易用性(是的,API的质量)您还没有公布不使用Java本机实现的任何具体原因。vtd-xml在性能/内存使用和易用性方面将是最受欢迎的。您会选择哪一个,为什么选择?其实并不重要。两者都是内置在JDK中的SAX和DOM解析器的包装器。W3C文档层次结构冗长且难以使用,因此DOM4J和JDOM都试图使其更简单。我喜欢Elliott Rusty Harold,所以我倾向于首先使用JDOM。DOM是W3C标准()。JAXP标准()涵盖了该标准的Java实现。JAXP然后由不同的提供者实现,如Oracle、Apache等。事实上,如果不是这样的话,没有人会使用DOM(a)它被定义为一个标准并有多个实现,(b)它默认包含在JDK中。从所有其他角度来看,JDOM2和XOM更可取。@Natix这就是为什么“编辑”选项适用于。现在应该更好了。@Kikiwa异常处理从这篇文章中删除了尽可能多的内容。如果