使用JAVA比较两个XML文件

7
我有两个几乎相同的XML文件,分别为abc.xml和123.xml,但后者123.xml比前者abc.xml多了一些内容。我想使用Java读取这两个文件,并比较abc.xml中每个标签中的内容是否与123.xml中的内容相同,类似于对象比较。请建议如何使用Java读取XML文件并开始进行比较。
谢谢。

2
在您的情况下,我可能会建议使用DOM解析器(前提是您的文件不是很大)。然后,您将有效地拥有您的对象,并且可以逐个字段进行比较。 - Aleks G
如果有两个具有相同标签的节点会怎样?它们将如何进行比较? - Eugen Martynov
实际上,abc.xml 的所有内容都包含在 123.xml 中。我只想检查 abc.xml 中带有标签的元素是否存在于 123.xml 中。 - Sangram Anand
7个回答

13
如果你只想比较的话,可以使用这个:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setCoalescing(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();

Document doc1 = db.parse(new File("file1.xml"));
doc1.normalizeDocument();

Document doc2 = db.parse(new File("file2.xml"));

doc2.normalizeDocument();
Assert.assertTrue(doc1.isEqualNode(doc2));

否则,请参见此http://xmlunit.sourceforge.net/


如果其中一个 XML 文档有命名空间,而另一个没有,这个能用吗? - ziggy

5
我会选择使用XMLUnit。 它提供的功能包括:
  • 比较两个XML片段之间的差异
  • 使用XSLT转换XML片段后的结果
  • 在XML片段上执行XPath表达式的评估
  • 检查XML片段的有效性
  • 通过DOM遍历公开的XML片段中的单个节点
祝你好运!

4
我会使用JAXB从XML文件生成Java对象,然后比较Java文件。这样做可以使处理变得更加容易。

3
一般来说,如果您知道有两个具有相同结构但内容略有不同且无序的文件,您需要“读取”这些文件以比较其内容。
如果您拥有XML文件的XML模式,则可以使用JAXB创建一组类,以表示由XML模式定义的特定DOM。这种方法的好处是,您不必通过通用函数解析XML文件的元素和属性,而是通过实际对问题有意义的字段进行解析。
当然,为了能够检测到两个文件中相同条目的存在,您需要通过一些公共字段(例如某个ID)将它们“匹配”。
为了帮助您发现重复项,您可以使用Java集合中的一些相关数据结构,如Set(或其派生类之一)。
希望这有所帮助。

2
正确的方法取决于两个因素:
(a)您希望控制比较方式的程度有多大?例如,您是否需要控制空格是否重要,是否应忽略注释,是否应忽略命名空间前缀,是否应忽略冗余的命名空间声明,是否应忽略XML声明?
(b)您想要什么答案?(i)一个布尔值:相同/不同,(ii)适合人类处理的差异列表,(iii)适合应用程序处理的差异列表。
我使用的两种技术是:(a)将两个文件都转换为规范化的XML,然后比较字符串。这几乎没有任何控制,并且只给出布尔结果。(b)使用XPath 2.0 deep-equal()函数或扩展的Saxon版本saxon:deep-equal()比较两个树。 Saxon版本可以更好地控制比较的方式,并提供了更详细的差异报告(供人类阅读,而不是应用程序使用)。
如果您想编写Java代码,当然可以实现自己的比较逻辑-例如,您可以找到XPath deep-equal的开源实现,并修改它以满足您的要求。这只是一百行左右的代码。

1

如果你只是想比较和显示,那么你可以使用Guiffy

这是一个很好的工具。如果你想在后端进行处理,那么你必须使用DOM解析器将两个文件加载到2个DOM对象中,并逐个比较属性。


0

这有点过头了,但如果你的XML有架构,你可以将其转换为EMF元模型,然后使用EMF Compare进行比较。


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