0

我已经用谷歌搜索过这个问题,我知道还有 10 个其他类似的问题,但我似乎无法让它发挥作用..

我想比较 2 个 xml 字符串,只得到拼写错误或类似内容的差异,而忽略子顺序。这是我的代码自动取款机:

    public void xmlCompare() {

    try {
        // First XML-read
        InputStream is = new FileInputStream("xmlTestCorrect.xml");
        String xmlText = IOUtils.toString(is);

        // Second XML-read
        InputStream is2 = new FileInputStream("xmlTestFalse.xml");
        String xmlText2 = IOUtils.toString(is2);

        Diff diff = DiffBuilder.compare(Input.fromString(xmlText)).withTest(Input.fromString(xmlText2))
                .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)).ignoreWhitespace()
                .ignoreComments().checkForSimilar().build();

        System.out.println(diff.hasDifferences());
        System.out.println(diff.getDifferences());

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

而我的结果....

 Expected text value 'commons-io' but was 'org.json'
 Expected text value 'commons-io' but was 'json'

等等。我刚刚在 xmlTestFalse.xml 文件中切换了一些依赖项(还添加了一些成功显示的拼写错误)。并且仍然注意到切换的依赖关系。为什么??我尝试做这样的事情,因为我有相同版本的 xmlunit:像这样

4

1 回答 1

0

您需要问自己“什么标识了应该相互比较的 XML 树”——然后向 XMLUnit 解释它:-)

请查看https://github.com/xmlunit/user-guide/wiki/SelectingNodes

您没有显示您要比较的 XML,所以我猜它类似于 Maven POM。

假设你想拥有

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
</dependency>
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
</dependency>

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
</dependency>
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
</dependency>

作为“相似”的结果。

这里要意识到的重要一点是您需要选择正确的dependency元素。如果你试图匹配正确的groupId元素,那就太迟了。一旦 XMLUnit 确定了一个dependency元素,该子树内就只有一个groupId元素。

您已经告诉 XMLUnit 通过元素名称来匹配节点。这意味着dependency元素按文档顺序匹配,这不是您想要的。您可能想要“匹配元素名称和名为的子元素的文本值artifactId”之类的内容。

不过,对于 POM 的其余部分,像这样的选择器将毫无用处。大多数其他元素根本没有artifactId孩子。这就是条件选择器发挥作用的地方。您需要ElementSelectors.byName用“更复杂”的东西替换。这个

ElementSelectors.conditionalBuilder()
   .whenElementIsNamed("dependency")
   .thenUse(ElementSelectors.byXPath("./artifactId",
                                     ElementSelectors.byNameAndText))
   .elseUse(ElementSelectors.byName)
   .build()

应该适用于dependencyXML 元素的所有“简单”情况。如果有更复杂的情况,您需要添加更多条件。

于 2016-06-30T18:06:30.937 回答