在Java中使用XPath比较两个忽略某些元素的xml文件

mxg2im7a  于 2023-01-01  发布在  Java
关注(0)|答案(2)|浏览(96)

如何使用XPath比较两个XML文件,而忽略某些元素?
例如,我需要比较下面的两个XML文件,但是我需要忽略'Date'元素,方法是在运行期间传递此元素的Xpath(//Set[1]/Product[\1]/Date)。要忽略的元素可能每次都不同。
XML文件1:

<?xml version="1.0" encoding="utf-8"?>
<Set
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:abc:product:v3" xsi:schemaLocation="urn:abc:product:v3 abc.xsd">
    <Product>
        <id>1</id>
        <ref>1</ref>
        <Date>2021-09-19</Date>
        <company>JJ</company>
        <lastModified>2021-09-20T21:00:30</lastModified>
        <productOne>
            <partProduct>
                <Level>3.0</Level>
                <Flag>0</Flag>
                <Code>EN</Code>
            </partProduct>
        </productOne>
    </Product>
</Set>

XML文件2:

<?xml version="1.0" encoding="utf-8"?>
<Set
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:abc:product:v3" xsi:schemaLocation="urn:abc:product:v3 abc.xsd">
    <Product>
        <id>2</id>
        <ref>2</ref>
        <Date>2021-09-20</Date>
        <company>JJ</company>
        <lastModified>2021-09-20T21:00:30</lastModified>
        <productOne>
            <partProduct>
                <Level>3.0</Level>
                <Flag>0</Flag>
                <Code>EN</Code>
            </partProduct>
        </productOne>
    </Product>
</Set>
gwo2fgha

gwo2fgha1#

需要通过删除要忽略的元素,将两个文件转换为比较结果相等的形式。通常使用XSLT完成此操作。转换后,可以使用XPath 2.0函数deep-equal()比较结果,或者将两个文档序列化为规范XML,然后在字符或二进制级别比较文件。
为此,我将运行XQuery Update删除路径表达式选择的节点,然后使用fn:deep-equal()比较结果文档,或者执行规范序列化并比较结果词法形式。
作为XQuery Update的替代方法,可以使用xmlstarlet或Saxon的Gizmo工具。
但这可能取决于您希望从比较中得到什么。如果您希望得到是/否的答案,上面的方法很好,但获取差异的详细信息会比较困难。您可以编写自己的查询来查找差异,或使用DeltaXML之类的工具。

**注意:**此答案随后被第三方编辑,其方式使评论线程变得毫无意义。请忽略评论。

dgsult0t

dgsult0t2#

如果使用XmlUnit,则可以为节点定义筛选器:

Diff myDiff = DiffBuilder.compare(controlXml)
    .withTest(testXml)
    // Ignore all nodes with 'Date' name
    .withNodeFilter(node -> !"Date".equals(node.getNodeName()))
    .build();

相关问题