有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java XmlUnit在比较XML文件时忽略元素的顺序

我有以下两个xml文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pricebooks xmlns="http://www.blablabla.com">
    <pricebook>
        <header pricebook-id="my-id">
            <currency>GBP</currency>
            <display-name xml:lang="x-default">display name</display-name>
            <description>my description 1</description>
        </header>
        <price-tables>
            <price-table product-id="id1" mode="mode1">
                <amount quantity="1">30.00</amount>
            </price-table>
            <price-table product-id="id2" mode="mode2">
                <amount quantity="1">60.00</amount>
            </price-table>
        </price-tables>
    </pricebook>
</pricebooks>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<pricebooks xmlns="http://www.blablabla.com">
    <pricebook>
        <header pricebook-id="my-id">
            <currency>GBP</currency>
            <display-name xml:lang="x-default">display name</display-name>
            <description>my description 1</description>
        </header>
        <price-tables>
            <price-table product-id="id2" mode="mode2">
                <amount quantity="1">60.00</amount>
            </price-table>
            <price-table product-id="id1" mode="mode1">
                <amount quantity="1">30.00</amount>
            </price-table>
        </price-tables>
    </pricebook>
</pricebooks>

忽略元素price-table的顺序,我试图对其进行比较,所以对我来说,这两个元素是相等的。我在用

        <dependency>
            <groupId>org.xmlunit</groupId>
            <artifactId>xmlunit-core</artifactId>
            <version>2.5.0</version>
        </dependency>

代码如下,但我无法让它工作。它抱怨是因为属性值id1id2不同

Diff myDiffSimilar = DiffBuilder
    .compare(expected)
    .withTest(actual)
    .checkForSimilar()
    .ignoreWhitespace()
    .ignoreComments()
    .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))
    .build();
assertFalse(myDiffSimilar.hasDifferences());

我还尝试对节点匹配器进行如下编辑:

.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
    .whenElementIsNamed("price-tables")
    .thenUse(ElementSelectors.byXPath("./price-table", ElementSelectors.byNameAndText))
    .elseUse(ElementSelectors.byName)
    .build()))

谢谢你的帮助


共 (1) 个答案

  1. # 1 楼答案

    我在price-table元素中根本看不到任何嵌套文本,因此byNamAndText只在元素名称上匹配——这对所有price-table元素都是一样的,因此不符合您的要求

    在你的例子中,price-tables没有歧义,因为反正只有一个。所以byXPath方法看起来是错误的。至少在代码片段中,除了price-table元素之外,XMLUnit应该可以处理byName

    我不确定是product-id单独识别price-table元素还是所有属性的组合。无论是byNameAndAttributes("product-id")还是它的byNameAndAllAttributes表亲都应该起作用

    如果它是product-id,那么对于所有没有任何product-id属性的元素,byNameAndAttributes("product-id")就变成了byName。在这种特殊情况下byNameAndAttribute("product-id")本身就可以处理我们所看到的整个文档——或多或少是出于偶然

    如果您需要比price-table更复杂的其他元素规则,或者您希望使事情比price-table更明确

    ElementSelectors.conditionalBuilder()
        .whenElementIsNamed("price-table")
        .thenUse(ElementSelectors.byNameAndAttributes("product-id"))
        // more special cases
        .elseUse(ElementSelectors.byName)
    

    是更好的选择