在Java中读取XML的最佳方法

11

我从其他应用程序中获取了一个XML文件。

我想逐个读取这个XML文件的节点,并将节点值存储到数据库中以供进一步使用。

那么,使用Java读取XML文件和检索节点值的最佳方式/API是什么?


3
"最佳" 取决于其他因素,如内存使用等。 - Thorbjørn Ravn Andersen
请查看我对类似问题的回答:http://stackoverflow.com/questions/7172212/how-to-convert-a-java-object-to-a-xml-string-on-the-contrary-convert-xml-to-a-jav/7173634#7173634 - bdoughan
8个回答

7

有各种各样的工具可以用来处理XML。今天,我比较喜欢以下两个:

这里有一个很好的比较Simple和JAXB的文章:http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-simple.html

就个人而言,我更喜欢Simple,因为Niall提供了非常好的支持,但是JAXB(如上面的博客文章所述)可以用更少的代码生成更好的输出。

StAX是一个更基本的API,它允许您读取XML文档,这些文档无法简单地逐个加载到RAM中(Simple和JAXB都不允许您“逐个”读取XML文档 - 它们总是会尝试一次性将所有内容加载到RAM中)。


JAXB也同样易于使用:http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-simple.html - bdoughan
JAXB并没有“拥有”一个流API,而是使用了StAX。它可以独立正常工作。事实上,除非询问者的XML具有一些复杂的结构,否则StAX可能对他的工作已经足够了。 - G_H
简单的XML使用StAX,它与SAX一样高效,因此可以很好地处理大文件。 - ng.
谢谢,我已经改进了我的回答。 - Aaron Digulla

4

我建议使用XPath。Xalan已经包含在JDK中(不需要外部jar文件),并且它符合您的要求,即遍历元素节点(我假设)并存储它们的文本值。例如:

    String xml = "<root> <item>One</item> <item>Two</item> <item>Three</item> </root>";

    XPathFactory xpf = XPathFactory.newInstance();
    InputSource is = new InputSource(new StringReader(xml));
    NodeList nodes = (NodeList) xpf.newXPath().evaluate("/*/*", is,
            XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); ++i) {
        Element e = (Element) nodes.item(i);
        System.out.println(e.getNodeName() + " -> " + e.getTextContent());
    }
}

这个例子返回所有非根元素的列表,并打印出相应的元素名称和文本内容。根据你的需求调整xpath表达式。


4
我建议如果您能够管理,可以使用简单的XML工具。
例如,我和我的同事们曾经引入过复杂的XML框架,在一开始就像魔法一样运行良好。然后你会忘记这个框架,你有专门的构建文件来映射XML到bean,你提供了一个新的障碍给你项目中的新开发人员。你失去了很多重构的自由。
最终,你会后悔在开始时使用复杂的框架来节省时间。我已经看到过多次,在重构时这些框架被抛弃,因为每个人都对它们产生了负面感受,尽管它们在纸上很棒。
因此,如果您很少使用它们,请三思而后行是否引入复杂的XML框架。如果您和您的团队经常使用它们,则应该采用这种方式。

2

试试 Apache Xerces。它非常成熟且稳定。其他可用的替代方案也可以,但一定不要开发自己的实现。


1
我很想给这个打负分;Xerces的API非常不友好。 - Aaron Digulla
@Aaron Digulla您有什么建议? - Swagatika

2
绕过解析XML并将值存储到数据库的问题,我想质疑上述操作的必要性。现在大多数数据库都可以处理XML,因此可以以某种方式将其存储到表中,而不需要解析内容;在表中的列中包含的XML内容通常可以通过使用“xmlselect()”和类似函数进行查询。
想一想:如果将来从其他应用程序获取的XML内容发生更改,则需要进行大量更改。如果经常更改,这将成为一场噩梦。
祝好, Wim

不,我无法存储XML。因为我可以通过填写表单或者已经存在的XML格式来获取数据,为了保持一致性,我必须将节点值存储到数据库中。 - Romani
抱歉,我不理解。你说你从其他应用程序中“获取”了XML。是什么阻止你将其直接保存在数据库中呢? - Wivani

1

dom4jjdom都很容易使用(暂时不考虑“最好”的要求;))


3
请注意,JDOM 已经几乎停滞不前,甚至没有使用 Java 5(泛型)来避免很多强制类型转换。 - Aaron Digulla
我投票支持jdom,因为它很好用,易于上手。以前经常使用它,现在却很怀念它 :( 现在更多的是使用“企业级”XML框架,尽管我现在处理的任务更加自动化和复杂。 - user425367
@Aaaron Digulla - 你让我感觉很老,我曾经经常使用它 - 看起来好像是几年/几十年前的事情;-) - Andreas Dolk
2
JDOM已经停止更新了?我不知道这个消息。我一直在使用它,但是大约一年前开始避免使用它,因为我正在寻找更节省内存的解决方案。说到这个,除非你真的需要将整个XML树保存在内存中,否则我总是建议避免使用任何类似DOM的解决方案。 - G_H
JDOM有了泛型支持的新版本。JDOM 2.0.0将JDOM带入了泛型世界,以及其他Java 5中引入的语言元素。http://www.jdom.org/news/index.html - Christophe Roussy

0

试试XStream,这个非常简单。


JAXB也很容易使用:http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-xstream.html - bdoughan

0

嗯,我使用了Stax来解析相当大量的XML节点,它比Dom和sax消耗更少的内存,因为它是一种拉取XML数据的方式。对于大型XML数据节点,Stax可能是一个不错的选择。


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