在XMLUnit 2.9的DifferenceEvaluator中,如何获取节点名称处理属性比较?
问题描述
使用org.xmlunit 2.9比较两个XML文件时,需要处理特殊场景:当XML1包含<version value="12.3" />、XML2包含<version value="12.345" />时,应判定这两个节点的属性值相等。当前实现的DifferenceEvaluator依赖具体的属性值(比如判断是否等于"12.3"),希望改为**基于节点名称(检查是否为version元素)**来触发属性值的特殊比较逻辑,不再依赖固定值。
原代码如下:
DifferenceEvaluator ResponseEvaluator = new DifferenceEvaluator() { public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { if(outcome != ComparisonResult.EQUAL) { if(comparison.getControlDetails().getValue() != null && comparison.getTestDetails().getValue() != null && comparison.getControlDetails().getValue().toString().equals("12.3")) { if(comparison.getType() != null && comparison.getType() == ComparisonType.ATTR_VALUE && comparison.getTestDetails().getValue().toString().contains("12")) { return ComparisonResult.EQUAL; } } } // 原代码缺少默认返回语句,此处补充 return outcome; } };
解决方案
完全可以实现基于节点名称的判断逻辑。核心要点是:当比较的是属性值(ComparisonType.ATTR_VALUE)时,获取该属性所属的元素节点,判断元素名称是否为version,再执行属性值的特殊比较逻辑。
修改后的代码如下:
DifferenceEvaluator ResponseEvaluator = new DifferenceEvaluator() { @Override public ComparisonResult evaluate(Comparison comparison, ComparisonResult outcome) { // 仅在原结果不相等时处理特殊逻辑 if (outcome != ComparisonResult.EQUAL) { // 限定处理属性值比较的场景 if (comparison.getType() == ComparisonType.ATTR_VALUE) { Node controlAttr = comparison.getControlDetails().getNode(); Node testAttr = comparison.getTestDetails().getNode(); // 确保节点为属性类型,且所属元素是version节点 if (controlAttr instanceof Attr && testAttr instanceof Attr) { Element controlElement = ((Attr) controlAttr).getOwnerElement(); Element testElement = ((Attr) testAttr).getOwnerElement(); if ("version".equals(controlElement.getNodeName()) && "version".equals(testElement.getNodeName())) { // 自定义属性值比较逻辑:示例为匹配主版本号(适配12.3和12.345的场景) String controlValue = comparison.getControlDetails().getValue().toString(); String testValue = comparison.getTestDetails().getValue().toString(); String controlMainVersion = controlValue.split("\\.")[0]; String testMainVersion = testValue.split("\\.")[0]; if (controlMainVersion.equals(testMainVersion)) { return ComparisonResult.EQUAL; } // 若无需版本匹配,只要是version节点的value属性就判定相等,可替换为: // return ComparisonResult.EQUAL; } } } } // 返回原结果,不干扰其他节点的正常比较 return outcome; } };
代码说明
- 节点类型校验:因为比较的是属性值,先获取属性节点(
Attr类型),再通过getOwnerElement()拿到所属的version元素,避免误判其他元素的属性。 - 属性值逻辑自定义:示例采用提取主版本号(小数点前部分)的方式,确保主版本一致的场景判定为相等;你可以根据需求调整逻辑,比如直接判定所有
version节点的value属性相等。 - 默认结果保留:仅处理
version节点的属性差异,其他节点的比较结果不受影响。
内容的提问来源于stack exchange,提问作者totoro
相关产品推荐
相关产品推荐

