比较XML忽略子命令

时间:2016-06-29 19:18:27

标签: java xml xmlunit-2

我已经google了这个,我知道还有其他10个这样的问题,但我似乎无法让它发挥作用..

我想比较2个xml字符串,只得到拼写错误或类似内容的差异,同时忽略子订单。这是我的代码atm:

    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:like this

1 个答案:

答案 0 :(得分: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()

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