我有 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>
请注意,在测试 XML 中,添加了另一个序列,并删除了第一个序列的最后一个元素(国家/地区(。
XMLUnit抱怨没有名为city
的元素,该元素位于第二个序列中。它按顺序获取元素。我尝试覆盖ELementName和AttributeQualifier,但没有产生预期的结果。此外,覆盖RecursiveElemenNameAndTextQualifier也无济于事。RecursiveElemenNameAndTextQualifier不起作用的原因是因为第一个序列不匹配。我将如何处理并确保
public boolean qualifyForComparison(Element element, Element element1)
{
// should return true only when **element 1** has all elements of **element**
}
真的比"忽略元素顺序"复杂一点,不是吗? :-(
ElementNameAndAttributeQualifier
对于xs:element
元素来说很好,但您真正的问题是让 XMLUnit 选择正确的xs:sequence
元素。我真的建议您使用 XMLUnit 2.x,因为它的条件元素选择器构建器是您需要的,并且在 XMLUnit 1.x 中复制它有点痛苦。
如果您的自定义元素选择器按照您的评论进行操作,那么您根本不会选择要比较xs:sequence
元素。"测试"序列不包含"街道"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();
当为差分发动机供电时。