【问题标题】:XmlUnit ignore order of elements when comparing XML filesXmlUnit 在比较 XML 文件时忽略元素的顺序
【发布时间】:2019-09-07 17:10:44
【问题描述】:

我有以下两个 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());

我也尝试编辑 nodeMatcher 如下:

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

感谢您的帮助。

【问题讨论】:

    标签: java xml java-8 diff xmlunit-2


    【解决方案1】:

    我在您的 price-table 元素中根本看不到任何嵌套文本,因此 byNamAndText 仅匹配元素名称 - 这对于所有 price-tables 都是相同的,因此不会按照您的意愿行事。

    在您的示例中,price-tables 没有歧义,因为无论如何只有一个。所以byXPath 方法看起来是错误的。至少在您的 sn-p XMLUnit 中,除了 price-table 元素之外,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)
    

    是更好的选择。

    【讨论】:

      猜你喜欢
      • 2018-08-16
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多