我有2个XML。我一直在使用XMLUnit来比较2个xml字符串。问题是我无法忽略元素出现的顺序。我尝试重写ElementQualifier以及DifferenceListener,但这对这种情况没有帮助。
控制XML
<xs:complexType>
<xs:anotation>
<xs:description>
<Description>Country</Description>
</xs:description>
</xs:anotation>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
测试XML
<xs:complexType>
<xs:anotation>
<xs:description>
<Description>Country</Description>
</xs:description>
</xs:anotation>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
</xs:sequence>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
</xs:sequence>
</xs:complexType>
请注意,在Test XML中添加了另一个序列,并删除了第一个序列的最后一个元素(国家/地区)。
XMLUnit抱怨没有第二个序列中名为city
的元素。它采用了有序的元素。我尝试覆盖 ELementNameAndAttributeQualifier ,但没有产生所需的结果。另外,覆盖 RecursiveElemenNameAndTextQualifier 也没有帮助。 RecursiveElemenNameAndTextQualifier 的原因不起作用,因为theres与第一个序列不匹配。我将如何处理并确保
public boolean qualifyForComparison(Element element, Element element1)
{
// should return true only when **element 1** has all elements of **element**
}
答案 0 :(得分:1)
这实际上比&#34;忽略元素顺序&#34;更复杂,不是吗? : - )
ElementNameAndAttributeQualifier
适用于xs:element
元素,但您真正的问题是让XMLUnit选择正确的xs:sequence
元素。我真的建议你使用XMLUnit 2.x,因为它的条件元素选择器构建器是你需要的,并且在XMLUnit 1.x中复制它是有点痛苦的。
如果您的自定义元素选择器执行了您的评论所说的内容,则您根本不会选择要比较的xs:sequence
元素。 &#34;测试&#34;序列没有包含&#34; street&#34; xs:element
,ElementNameQualifier
将返回false
。
我不确定你想要的确切逻辑是什么样的。您在评论中描述的内容类似于(使用XMLUnit 2.x,未经测试)
public boolean canBeCompared(Element e1, Element e2) {
NodeList e1Children = e1.getChildNodes();
NodeList e2Children = e2.getChildNodes();
Iterable<Map.Entry<Node, Node>> matches =
new DefaultNodeMatcher(ElementSelectors.byNameAndAllAttributes)
.match(new IterableNodeList(e1Children), new IterableNodeList(e2Children));
for (Map.Entry<Node, Node> m : matches) {
if (m.getKey() == null // test child with no matching control child
|| m.getValue() == null // control child with no matching test child
) {
return false;
}
}
return true;
}
没有内置的方法可以做到这一点,你真的需要自己对抗DOM。
最后你要使用像
这样的东西ElementSelectors.conditionalBuilder()
.whenElementIsNamed(new QName("sequence", XMLConstants.W3C_XML_SCHEMA_NS_URI))
.thenUse(the element selector built above)
.elseUse(ElementSelectors.byNameAndAllAttributes)
.build();
喂食差异引擎时。