XML 单位 - 在不同的 xml 元素上使用自定义元素选择器
XML Unit - Using custom element selectors on different xml elements
我在将 xml 文档中的各种元素与 XMLUnit (2.2.1) 进行比较时遇到问题。在我的文档中有几个 xml 元素,我想
知道它们是否彼此不同。但是,我不想以相同的方式比较所有 xml 元素。有时我只想通过它们进行比较 name.In 其他情况我想通过名称和属性或名称和文本进行比较。
这是一个例子(见评论)
控制
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<LANGUAGES>
<!-- Compare LANGUAGE by Name and Attribute -->
<LANGUAGE VALUE="DE" />
<LANGUAGE VALUE="EN" />
<LANGUAGE VALUE="IT" />
<LANGUAGE VALUE="FR" />
</LANGUAGES>
<CODES>
<!-- Compare CODE by Name and Text -->
<CODE>10000-1</CODE>
<CODE>20000-2</CODE>
<CODE>30000-3</CODE>
<CODE>40000-4</CODE>
</CODES>
<CONTACT> <!-- Compare CONTACT and Children just by Name -->
<FIRSTNAME>Max</FIRSTNAME>
<SURNAME>Mustermann</SURNAME>
</CONTACT>
</ROOT>
测试:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<LANGUAGES>
<!-- Compare LANGUAGE by Name and Attribute -->
<LANGUAGE VALUE="DE" />
<LANGUAGE VALUE="FR" />
</LANGUAGES>
<CODES>
<!-- Compare CODE by Name and Text -->
<CODE>20000-2</CODE>
<CODE>40000-4</CODE>
</CODES>
<CONTACT> <!-- Compare CONTACT and Children by Name -->
<FIRSTNAME>Tim</FIRSTNAME>
<SURNAME>Mustermann</SURNAME>
</CONTACT>
</ROOT>
我尝试将 ElementSelectors 与 ElementSelectors.conditionalBuilder (https://github.com/xmlunit/user-guide/wiki/SelectingNodes#conditional-elementselectors) 结合使用,以仅将 ElementSelector 应用于特定元素 (whenElementIsNamed)。也许这不是我想要实现的目标的正确方法。
这是我用于测试的代码:
public void xmlDiff() {
String control = getControlDocument(); //
String test = getTestDocument(); //
Diff myDiff = DiffBuilder.compare(control)//
.withTest(test) //
.ignoreWhitespace() //
.ignoreComments() //
.checkForSimilar() //
.withNodeMatcher(new DefaultNodeMatcher(partialElementSelector("LANGUAGE", ElementSelectors.byNameAndAllAttributes), partialElementSelector("CODE",ElementSelectors.byNameAndText), ElementSelectors.byName)) //
.build();
assertThat(myDiff.hasDifferences()).isTrue(); //
}
private ElementSelector partialElementSelector(final String expectedName, final ElementSelector elementSelector) {
return ElementSelectors.conditionalBuilder().whenElementIsNamed(expectedName).thenUse(elementSelector).build();
}
我真正需要的是两个 LANGUAGE (EN,IT) 和两个 CODE (10000-1,30000-3) 已被删除(未替换)并且 FIRSTNAME 已更改的信息。
无论有无 XML 单元 (DiffBuilder),我如何获得这些信息?
感谢您的帮助!
在 DefaultNodeMatcher
的构造函数中使用三个 ElementSelector
与在多个条件下使用单个 ElementSelector
之间存在细微差别。
你想用三个选择器实现的也可以写成
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("LANGUAGE")
.thenUse(ElementSelectors.byNameAndAllAttributes)
.whenElementIsNamed("CODE")
.thenUse(ElementSelectors.byNameAndText)
.elseUse(ElementSelectors.byName)
.build();
乍一看,这似乎是一样的,但事实并非如此。事实上它会起作用。这是我从你的例子中得到的:
Expected child nodelist length '4' but was '2' - comparing <LANGUAGES...> at /ROOT[1]/LANGUAGES[1] to <LANGUAGES...> at /ROOT[1]/LANGUAGES[1] (DIFFERENT)
Expected child 'LANGUAGE' but was 'null' - comparing <LANGUAGE...> at /ROOT[1]/LANGUAGES[1]/LANGUAGE[2] to <NULL> (DIFFERENT)
Expected child 'LANGUAGE' but was 'null' - comparing <LANGUAGE...> at /ROOT[1]/LANGUAGES[1]/LANGUAGE[3] to <NULL> (DIFFERENT)
Expected child nodelist length '4' but was '2' - comparing <CODES...> at /ROOT[1]/CODES[1] to <CODES...> at /ROOT[1]/CODES[1] (DIFFERENT)
Expected child 'CODE' but was 'null' - comparing <CODE...> at /ROOT[1]/CODES[1]/CODE[1] to <NULL> (DIFFERENT)
Expected child 'CODE' but was 'null' - comparing <CODE...> at /ROOT[1]/CODES[1]/CODE[3] to <NULL> (DIFFERENT)
Expected text value 'Max' but was 'Tim' - comparing <FIRSTNAME ...>Max</FIRSTNAME> at /ROOT[1]/CONTACT[1]/FIRSTNAME[1]/text()[1] to <FIRSTNAME ...>Tim</FIRSTNAME> at /ROOT[1]/CONTACT[1]/FIRSTNAME[1]/text()[1] (DIFFERENT)
所以这是发生了什么:当 XMLUnit 查看 LANGUAGE
和 VALUE
en
时,您构建的第一个条件 ElementSelector
将 return false
所有候选 LANGUAGE
元素。
当使用多参数 DefaultNodeMatcher
构造函数时,将询问下一个 ElementSelector
- 在您的情况下也会 return false
因为它只对以下内容感兴趣CODE
个元素。然后查询第三个 ElementSelector
,它将愉快地接受任何名为 LANGUAGE
.
的测试元素
当使用我在上面设置的单个 ElementSelector
时,一旦 Predicate
returned [=29=,组合选择器将永远不会咨询任何备选方案].这意味着一旦选择器 returned false
.
就不会再考虑 LANGUAGE
元素
我将尝试使用您的示例来更新 https://github.com/xmlunit/user-guide/wiki/SelectingNodes#nodematcher,并且很乐意得到您的帮助以改进文档。
我在将 xml 文档中的各种元素与 XMLUnit (2.2.1) 进行比较时遇到问题。在我的文档中有几个 xml 元素,我想 知道它们是否彼此不同。但是,我不想以相同的方式比较所有 xml 元素。有时我只想通过它们进行比较 name.In 其他情况我想通过名称和属性或名称和文本进行比较。
这是一个例子(见评论)
控制
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<LANGUAGES>
<!-- Compare LANGUAGE by Name and Attribute -->
<LANGUAGE VALUE="DE" />
<LANGUAGE VALUE="EN" />
<LANGUAGE VALUE="IT" />
<LANGUAGE VALUE="FR" />
</LANGUAGES>
<CODES>
<!-- Compare CODE by Name and Text -->
<CODE>10000-1</CODE>
<CODE>20000-2</CODE>
<CODE>30000-3</CODE>
<CODE>40000-4</CODE>
</CODES>
<CONTACT> <!-- Compare CONTACT and Children just by Name -->
<FIRSTNAME>Max</FIRSTNAME>
<SURNAME>Mustermann</SURNAME>
</CONTACT>
</ROOT>
测试:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<LANGUAGES>
<!-- Compare LANGUAGE by Name and Attribute -->
<LANGUAGE VALUE="DE" />
<LANGUAGE VALUE="FR" />
</LANGUAGES>
<CODES>
<!-- Compare CODE by Name and Text -->
<CODE>20000-2</CODE>
<CODE>40000-4</CODE>
</CODES>
<CONTACT> <!-- Compare CONTACT and Children by Name -->
<FIRSTNAME>Tim</FIRSTNAME>
<SURNAME>Mustermann</SURNAME>
</CONTACT>
</ROOT>
我尝试将 ElementSelectors 与 ElementSelectors.conditionalBuilder (https://github.com/xmlunit/user-guide/wiki/SelectingNodes#conditional-elementselectors) 结合使用,以仅将 ElementSelector 应用于特定元素 (whenElementIsNamed)。也许这不是我想要实现的目标的正确方法。
这是我用于测试的代码:
public void xmlDiff() {
String control = getControlDocument(); //
String test = getTestDocument(); //
Diff myDiff = DiffBuilder.compare(control)//
.withTest(test) //
.ignoreWhitespace() //
.ignoreComments() //
.checkForSimilar() //
.withNodeMatcher(new DefaultNodeMatcher(partialElementSelector("LANGUAGE", ElementSelectors.byNameAndAllAttributes), partialElementSelector("CODE",ElementSelectors.byNameAndText), ElementSelectors.byName)) //
.build();
assertThat(myDiff.hasDifferences()).isTrue(); //
}
private ElementSelector partialElementSelector(final String expectedName, final ElementSelector elementSelector) {
return ElementSelectors.conditionalBuilder().whenElementIsNamed(expectedName).thenUse(elementSelector).build();
}
我真正需要的是两个 LANGUAGE (EN,IT) 和两个 CODE (10000-1,30000-3) 已被删除(未替换)并且 FIRSTNAME 已更改的信息。
无论有无 XML 单元 (DiffBuilder),我如何获得这些信息?
感谢您的帮助!
在 DefaultNodeMatcher
的构造函数中使用三个 ElementSelector
与在多个条件下使用单个 ElementSelector
之间存在细微差别。
你想用三个选择器实现的也可以写成
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("LANGUAGE")
.thenUse(ElementSelectors.byNameAndAllAttributes)
.whenElementIsNamed("CODE")
.thenUse(ElementSelectors.byNameAndText)
.elseUse(ElementSelectors.byName)
.build();
乍一看,这似乎是一样的,但事实并非如此。事实上它会起作用。这是我从你的例子中得到的:
Expected child nodelist length '4' but was '2' - comparing <LANGUAGES...> at /ROOT[1]/LANGUAGES[1] to <LANGUAGES...> at /ROOT[1]/LANGUAGES[1] (DIFFERENT)
Expected child 'LANGUAGE' but was 'null' - comparing <LANGUAGE...> at /ROOT[1]/LANGUAGES[1]/LANGUAGE[2] to <NULL> (DIFFERENT)
Expected child 'LANGUAGE' but was 'null' - comparing <LANGUAGE...> at /ROOT[1]/LANGUAGES[1]/LANGUAGE[3] to <NULL> (DIFFERENT)
Expected child nodelist length '4' but was '2' - comparing <CODES...> at /ROOT[1]/CODES[1] to <CODES...> at /ROOT[1]/CODES[1] (DIFFERENT)
Expected child 'CODE' but was 'null' - comparing <CODE...> at /ROOT[1]/CODES[1]/CODE[1] to <NULL> (DIFFERENT)
Expected child 'CODE' but was 'null' - comparing <CODE...> at /ROOT[1]/CODES[1]/CODE[3] to <NULL> (DIFFERENT)
Expected text value 'Max' but was 'Tim' - comparing <FIRSTNAME ...>Max</FIRSTNAME> at /ROOT[1]/CONTACT[1]/FIRSTNAME[1]/text()[1] to <FIRSTNAME ...>Tim</FIRSTNAME> at /ROOT[1]/CONTACT[1]/FIRSTNAME[1]/text()[1] (DIFFERENT)
所以这是发生了什么:当 XMLUnit 查看 LANGUAGE
和 VALUE
en
时,您构建的第一个条件 ElementSelector
将 return false
所有候选 LANGUAGE
元素。
当使用多参数 DefaultNodeMatcher
构造函数时,将询问下一个 ElementSelector
- 在您的情况下也会 return false
因为它只对以下内容感兴趣CODE
个元素。然后查询第三个 ElementSelector
,它将愉快地接受任何名为 LANGUAGE
.
当使用我在上面设置的单个 ElementSelector
时,一旦 Predicate
returned [=29=,组合选择器将永远不会咨询任何备选方案].这意味着一旦选择器 returned false
.
LANGUAGE
元素
我将尝试使用您的示例来更新 https://github.com/xmlunit/user-guide/wiki/SelectingNodes#nodematcher,并且很乐意得到您的帮助以改进文档。