XmlUnit 在比较 XML 个文件时忽略元素的顺序
XmlUnit ignore order of elements when comparing XML files
我有以下两个 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>
代码如下,但我无法让它工作。它抱怨是因为属性值 id1
和 id2
不同。
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()))
感谢您的帮助。
我根本没有在您的 price-table
元素中看到任何嵌套文本,因此 byNamAndText
仅匹配元素名称 - 对于所有 price-table
和因此不会做你想做的事。
在您的示例中,price-tables
没有歧义,因为无论如何只有一个。所以 byXPath
方法看起来是错误的。至少在您的代码段中,XMLUnit 应该可以很好地处理 byName
,但 price-table
元素除外。
我不确定 product-id
是单独识别您的 price-table
元素还是所有属性的组合。 byNameAndAttributes("product-id")
或其 byNameAndAllAttributes
堂兄应该可以。
如果它是 只有 product-id
那么 byNameAndAttributes("product-id")
对于没有任何 product-id
的所有元素变成 byName
根本没有属性。在这种特殊情况下,仅 byNameAndAttribute("product-id")
就可以为您的整个文档工作,正如我们所看到的那样 - 或多或少是偶然的。
如果您需要比 price-table
更复杂的其他元素规则,或者您想使事情比
更明确
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("price-table")
.thenUse(ElementSelectors.byNameAndAttributes("product-id"))
// more special cases
.elseUse(ElementSelectors.byName)
是更好的选择。
我有以下两个 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>
代码如下,但我无法让它工作。它抱怨是因为属性值 id1
和 id2
不同。
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()))
感谢您的帮助。
我根本没有在您的 price-table
元素中看到任何嵌套文本,因此 byNamAndText
仅匹配元素名称 - 对于所有 price-table
和因此不会做你想做的事。
在您的示例中,price-tables
没有歧义,因为无论如何只有一个。所以 byXPath
方法看起来是错误的。至少在您的代码段中,XMLUnit 应该可以很好地处理 byName
,但 price-table
元素除外。
我不确定 product-id
是单独识别您的 price-table
元素还是所有属性的组合。 byNameAndAttributes("product-id")
或其 byNameAndAllAttributes
堂兄应该可以。
如果它是 只有 product-id
那么 byNameAndAttributes("product-id")
对于没有任何 product-id
的所有元素变成 byName
根本没有属性。在这种特殊情况下,仅 byNameAndAttribute("product-id")
就可以为您的整个文档工作,正如我们所看到的那样 - 或多或少是偶然的。
如果您需要比 price-table
更复杂的其他元素规则,或者您想使事情比
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("price-table")
.thenUse(ElementSelectors.byNameAndAttributes("product-id"))
// more special cases
.elseUse(ElementSelectors.byName)
是更好的选择。