如何使用XMLUnit 2将子标签顺序调换的XML判定为相等?
让XMLUnit 2忽略子元素顺序判定XML相等的方案
当然有现成的解决方案啦!你碰到的是XMLUnit 2默认会严格校验子元素顺序的问题,要让这两个XML被判定为相等,只需要调整一下元素匹配器的配置就行,我给你几种常用的方案:
方案一:全局递归忽略顺序(简单通用)
如果你的场景中所有同名称的子元素顺序都不影响相等性,可以直接使用XMLUnit提供的ElementSelectors.byNameAndTextRecursive()匹配器,它会递归地根据元素名称和文本内容来匹配对应元素,完全忽略顺序。
示例代码:
import org.xmlunit.builder.DiffBuilder; import org.xmlunit.diff.Diff; import org.xmlunit.diff.ElementSelectors; public class XmlComparison { public static void main(String[] args) { String xml1 = "<composite> <data> <subtag> <code>1</code> </subtag> <subtag> <code>2</code> </subtag> </data> </composite>"; String xml2 = "<composite> <data> <subtag> <code>2</code> </subtag> <subtag> <code>1</code> </subtag> </data> </composite>"; Diff diff = DiffBuilder.compare(xml1) .withTest(xml2) // 核心配置:按名称+递归文本匹配,忽略顺序 .withNodeMatcher(ElementSelectors.byNameAndTextRecursive()) .build(); System.out.println("两个XML是否相等?" + !diff.hasDifferences()); // 输出true } }
方案二:仅针对特定节点忽略顺序(更灵活)
如果只有<data>下的<subtag>需要忽略顺序,其他节点仍要校验顺序,可以自定义条件化的元素选择器:
import org.xmlunit.diff.ElementSelector; import org.xmlunit.diff.ElementSelectors; import org.xmlunit.builder.DiffBuilder; import org.xmlunit.diff.Diff; public class XmlComparison { public static void main(String[] args) { String xml1 = "<composite> <data> <subtag> <code>1</code> </subtag> <subtag> <code>2</code> </subtag> </data> </composite>"; String xml2 = "<composite> <data> <subtag> <code>2</code> </subtag> <subtag> <code>1</code> </subtag> </data> </composite>"; // 自定义选择器:对data节点下的子元素用递归文本匹配,其他节点用默认的按名称顺序匹配 ElementSelector customSelector = ElementSelectors.conditionalBuilder() .whenElementIsNamed("data") .thenUse(ElementSelectors.byNameAndTextRecursive()) .elseUse(ElementSelectors.byName()) .build(); Diff diff = DiffBuilder.compare(xml1) .withTest(xml2) .withNodeMatcher(customSelector) .build(); System.out.println("两个XML是否相等?" + !diff.hasDifferences()); // 输出true } }
方案三:精准匹配特定子元素的值(更严谨)
如果你只想基于<subtag>下的<code>文本值来匹配元素(而不是所有文本内容),可以用byNameAndSelector结合XPath来实现:
import org.xmlunit.diff.ElementSelector; import org.xmlunit.diff.ElementSelectors; import org.xmlunit.builder.DiffBuilder; import org.xmlunit.diff.Diff; public class XmlComparison { public static void main(String[] args) { String xml1 = "<composite> <data> <subtag> <code>1</code> </subtag> <subtag> <code>2</code> </subtag> </data> </composite>"; String xml2 = "<composite> <data> <subtag> <code>2</code> </subtag> <subtag> <code>1</code> </subtag> </data> </composite>"; // 定义subtag的匹配规则:根据子元素code的文本值匹配 ElementSelector subtagMatcher = ElementSelectors.byNameAndSelector("subtag", ElementSelectors.byXPath("./code/text()", ElementSelectors.byText())); // 全局选择器:data节点下用自定义的subtag匹配规则,其他用默认顺序匹配 ElementSelector customSelector = ElementSelectors.conditionalBuilder() .whenElementIsNamed("data") .thenUse(subtagMatcher) .elseUse(ElementSelectors.byName()) .build(); Diff diff = DiffBuilder.compare(xml1) .withTest(xml2) .withNodeMatcher(customSelector) .build(); System.out.println("两个XML是否相等?" + !diff.hasDifferences()); // 输出true } }
这几种方案都能解决你的问题,你可以根据自己的实际场景选择最合适的一种~
内容的提问来源于stack exchange,提问作者gore_obsessed
相关产品推荐
相关产品推荐

