我正在搜索java库来解析XML(复杂的配置和数据文件),我在谷歌上搜索了一下,但除了dom4j之外找不到其他东西(似乎他们正在开发V2)..我看过commons的配置,但不喜欢,XML上的其他apache项目似乎处于Hibernate 状态.我没有亲自判断过dom4j,只是想知道——java还有其他(好的)开源xml解析库吗?你对dom4j的体验如何?

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

推荐答案

实际上,Java支持4种开箱即用的XML解析方法:

DOM Parser/Builder:整个XML struct 被加载到内存中,您可以使用众所周知的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解析器遍历文档并调用用户的回调方法.文档的开始/结束、元素等都有方法.它们是在组织中定义的.xml.萨克斯.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 Reader/Writer:它使用面向数据流的接口.当程序准备就绪时,它会像游标/迭代器一样请求下一个元素.您还可以使用它创建文档.

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文档的最新实现:是v2中Java6的一部分.这允许我们从文档中序列化java对象.阅读文档时使用了一个实现javax接口的类.xml.绑定解组器(您可以从JAXBContext.newInstance获得一个用于此的类).上下文必须使用使用的类进行初始化,但只需指定根类,而不必担心静态引用类.

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中缺少的任何特别有用的功能,标准库具有非常好的测试、记录和稳定的通常优势.

Java相关问答推荐

@GetMapping和@GetExchange有什么区别?

当在具有约束布局的AlertDialogue内部使用时,回收器视图布局宽度很奇怪

如果您仅同步写操作,Java布尔线程是否安全

方法没有用正确的值填充数组—而是将数组保留为null,'

如何使用jooq generator将表名和列名映射为人类可读的?

Jlink选项&-strie-ative-Commands";的作用是什么?

是否保证在事务性块的末尾标记违反约束?

具有阻塞方法的开源库是否应该为执行提供异步选项?

解释左移在Java中的工作原理

无法在Java中处理PayPal支付响应

如何将其他属性引用到log4j2 yaml配置中?

SonarLint:只能有条件地调用方法(S)

S,要对Java复制构造函数深度克隆所有属性进行单元测试,最可靠的方法是什么?

Domino Designer 14中的保存代理添加了重影库

Spring Boot&;Docker:无法执行目标org.springframework.boot:spring-boot-maven-plugin:3.2.0:build-image

JFree Chart从图表中删除边框

在Oracle db中,当我们提供字符串而不是数字时,比较是如何工作的?

在应用程序运行时更改LookAndFeel

java.lang.NoSuchMethodError:';org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream$Builder org.apache.poi-poi-ooxml-5.2.4

spring 数据Elastic search 与 spring 启动数据Elastic search 之间的区别是什么?