我要比较的两个 xml 是:
<root>
<a id ="tanvi">test</a>
<a id ="aj">ram</a>
<b id = "56">test</b>
<a id ="kartikey">test2</a>
<d>
<c foo = "bar">textchange</c>
</d>
</root>
和
<root>
<a id ="tanvi">test2</a>
<a id ="aj">ram</a>
<b id = "56">test</b>
<d>
<c foo = "bar">text</c>
</d>
<d>
<c foo = "soo">textchange</c>
</d>
</root>
我希望应用程序给我以下差异:
<a id ="tanvi">test2</a> vs <a id ="tanvi">test</a> text value change
<a id ="kartikey">test2</a> vs null not found
<c foo = "bar">text</c> vs <c foo = "bar">textchange</c> text value change
<d></d> not found
我已经尝试使用RecursiveElementNameAndTextQualifier
以及ElementNameAndAttributeQualifier
. 但我没有得到想要的结果。
我的代码如下:
public class Main {
public static void main(String[] args) {
DetailedDiff detailedDiff = null;
try {
FileReader base = new FileReader(new File(
"C:\\xml\\Test2\\test_Swap.txt"));
FileReader upgrade = new FileReader(new File(
"C:\\xml\\Test1\\test_Swap.txt"));
XMLUnit.setIgnoreWhitespace(Boolean.TRUE);
XMLUnit.setIgnoreAttributeOrder(Boolean.TRUE);
try {
detailedDiff = new DetailedDiff(XMLUnit.compareXML(base,
upgrade));
// detailedDiff
// .overrideElementQualifier(new
// ElementNameAndAttributeQualifier());
detailedDiff
.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
detailedDiff
.overrideDifferenceListener(new MyDifferenceListener());
} catch (SAXException | IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<Difference> listOfDifferences = detailedDiff.getAllDifferences();
for (Difference diff : listOfDifferences) {
if (diff.getId() == 22) {
if ((diff.getControlNodeDetail().getValue().equals("null") && diff
.getTestNodeDetail().getValue().equals("#text"))
|| (diff.getTestNodeDetail().getValue().equals("null") && diff
.getControlNodeDetail().getValue()
.equals("#text"))) {
System.out
.println("******************VALUE CHANGE*******************************");
System.out.print("Base Xpath: "
+ diff.getControlNodeDetail().getXpathLocation()
+ "\t");
System.out.println("Value: \'"
+ diff.getControlNodeDetail().getValue() + "\'\t");
System.out.print("Test Node Xpath: "
+ diff.getTestNodeDetail().getXpathLocation()
+ "\t");
System.out.print("Value: "
+ diff.getTestNodeDetail().getValue() + "\t");
System.out.println("Difference ID: " + diff.getId());
System.out.println("Difference: " + diff);
System.out.println("Description: " + diff.getDescription());
continue;
}
}
System.out
.println("*************************************************");
System.out.print("Base Xpath: "
+ diff.getControlNodeDetail().getXpathLocation() + "\t");
System.out.println("Value: \'"
+ diff.getControlNodeDetail().getValue() + "\'\t");
System.out.print("Test Node Xpath: "
+ diff.getTestNodeDetail().getXpathLocation() + "\'\t");
System.out.print("Value: \'" + diff.getTestNodeDetail().getValue()
+ "\'\t");
System.out.println("Difference ID: " + diff.getId());
System.out.println("Difference: " + diff);
System.out.println("Description: " + diff.getDescription());
}
}
}
*我正在使用DifferenceListener
忽略这些差异:
public class MyDifferenceListener implements DifferenceListener {
private static final int[] IGNORE_VALUES = new int[] {
DifferenceConstants.CHILD_NODELIST_LENGTH_ID,
DifferenceConstants.CHILD_NODELIST_SEQUENCE_ID,
DifferenceConstants.ATTR_SEQUENCE_ID,
DifferenceConstants.HAS_CHILD_NODES_ID };
static {
Arrays.sort(IGNORE_VALUES);
}
private boolean isIgnoredDifference(final Difference difference) {
int differenceId = difference.getId();
for (int element : IGNORE_VALUES) {
if (differenceId == element) {
return true;
}
}
return false;
}
@Override
public int differenceFound(final Difference difference) {
if (isIgnoredDifference(difference)) {
return RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
} else {
return RETURN_ACCEPT_DIFFERENCE;
}
}
@Override
public void skippedComparison(final Node node, final Node node1) {
// TODO Auto-generated method stub
}
}
这ElementNameAndAttributeQualifier
给了我这些结果:
*************************************************
Base Xpath: /root[1]/a[1]/text()[1] Value: 'test'
Test Node Xpath: /root[1]/a[1]/text()[1]' Value: 'test2' Difference ID: 14
Difference: Expected text value 'test' but was 'test2' - comparing <a ...>test</a> at /root[1]/a[1]/text()[1] to <a ...>test2</a> at /root[1]/a[1]/text()[1]
Description: text value
*************************************************
Base Xpath: /root[1]/a[3] Value: 'a'
Test Node Xpath: /root[1]/d[1]' Value: 'd' Difference ID: 10
Difference: Expected element tag name 'a' but was 'd' - comparing <a...> at /root[1]/a[3] to <d...> at /root[1]/d[1]
Description: element tag name
*************************************************
Base Xpath: /root[1]/a[3] Value: '1'
Test Node Xpath: /root[1]/d[1]' Value: '0' Difference ID: 11
Difference: Expected number of element attributes '1' but was '0' - comparing <a...> at /root[1]/a[3] to <d...> at /root[1]/d[1]
Description: number of element attributes
*************************************************
Base Xpath: /root[1]/a[3]/@id Value: 'id'
Test Node Xpath: /root[1]/d[1]' Value: 'null' Difference ID: 2
Difference: Expected attribute name 'id' but was 'null' - comparing <a...> at /root[1]/a[3]/@id to <d...> at /root[1]/d[1]
Description: attribute name
*************************************************
Base Xpath: /root[1]/a[3]/text()[1] Value: '3'
Test Node Xpath: /root[1]/d[1]/c[1]' Value: '1' Difference ID: 17
Difference: Expected node type '3' but was '1' - comparing <a ...>test2</a> at /root[1]/a[3]/text()[1] to <c...> at /root[1]/d[1]/c[1]
Description: node type
******************VALUE CHANGE*******************************
Base Xpath: null Value: 'null'
Test Node Xpath: /root[1]/d[1]/c[1]/text()[1] Value: #text Difference ID: 22
Difference: Expected presence of child node 'null' but was '#text' - comparing at null to <c ...>text</c> at /root[1]/d[1]/c[1]/text()[1]
Description: presence of child node
*************************************************
Base Xpath: /root[1]/d[1]/c[1]/@foo Value: 'bar'
Test Node Xpath: /root[1]/d[2]/c[1]/@foo' Value: 'soo' Difference ID: 3
Difference: Expected attribute value 'bar' but was 'soo' - comparing <c foo="bar"...> at /root[1]/d[1]/c[1]/@foo to <c foo="soo"...> at /root[1]/d[2]/c[1]/@foo
Description: attribute value
这RecursiveElementNameAndTextQualifier
给了我这些结果:
*************************************************
Base Xpath: /root[1]/a[1] Value: 'a'
Test Node Xpath: /root[1]/d[1]' Value: 'd' Difference ID: 10
Difference: Expected element tag name 'a' but was 'd' - comparing <a...> at /root[1]/a[1] to <d...> at /root[1]/d[1]
Description: element tag name
*************************************************
Base Xpath: /root[1]/a[1] Value: '1'
Test Node Xpath: /root[1]/d[1]' Value: '0' Difference ID: 11
Difference: Expected number of element attributes '1' but was '0' - comparing <a...> at /root[1]/a[1] to <d...> at /root[1]/d[1]
Description: number of element attributes
*************************************************
Base Xpath: /root[1]/a[1]/@id Value: 'id'
Test Node Xpath: /root[1]/d[1]' Value: 'null' Difference ID: 2
Difference: Expected attribute name 'id' but was 'null' - comparing <a...> at /root[1]/a[1]/@id to <d...> at /root[1]/d[1]
Description: attribute name
*************************************************
Base Xpath: /root[1]/a[1]/text()[1] Value: '3'
Test Node Xpath: /root[1]/d[1]/c[1]' Value: '1' Difference ID: 17
Difference: Expected node type '3' but was '1' - comparing <a ...>test</a> at /root[1]/a[1]/text()[1] to <c...> at /root[1]/d[1]/c[1]
Description: node type
******************VALUE CHANGE*******************************
Base Xpath: null Value: 'null'
Test Node Xpath: /root[1]/d[1]/c[1]/text()[1] Value: #text Difference ID: 22
Difference: Expected presence of child node 'null' but was '#text' - comparing at null to <c ...>text</c> at /root[1]/d[1]/c[1]/text()[1]
Description: presence of child node
*************************************************
Base Xpath: /root[1]/a[3]/@id Value: 'kartikey'
Test Node Xpath: /root[1]/a[1]/@id' Value: 'tanvi' Difference ID: 3
Difference: Expected attribute value 'kartikey' but was 'tanvi' - comparing <a id="kartikey"...> at /root[1]/a[3]/@id to <a id="tanvi"...> at /root[1]/a[1]/@id
Description: attribute value
*************************************************
Base Xpath: /root[1]/d[1]/c[1]/@foo Value: 'bar'
Test Node Xpath: /root[1]/d[2]/c[1]/@foo' Value: 'soo' Difference ID: 3
Difference: Expected attribute value 'bar' but was 'soo' - comparing <c foo="bar"...> at /root[1]/d[1]/c[1]/@foo to <c foo="soo"...> at /root[1]/d[2]/c[1]/@foo
Description: attribute value
ElementQualifier
我应该使用或覆盖任何方法来获得所需的结果?
-----------------编辑 1-------------------------------------------- ----------
XMLUnit.setCompareUnmatched(false)
与 结合使用时,ElementNameAndTextQualifier
可以正确识别差异。
使用它的结果是:
*************************************************
Base Xpath: /root[1]/a[1]/text()[1] Value: 'test2'
Test Node Xpath: /root[1]/a[1]/text()[1]' Value: 'test' Difference ID: 14
Difference: Expected text value 'test2' but was 'test' - comparing <a ...>test2</a> at /root[1]/a[1]/text()[1] to <a ...>test</a> at /root[1]/a[1]/text()[1]
Description: text value
*************************************************
Base Xpath: /root[1]/d[1]/c[1]/text()[1] Value: 'text'
Test Node Xpath: /root[1]/d[1]/c[1]/text()[1]' Value: 'textchange' Difference ID: 14
Difference: Expected text value 'text' but was 'textchange' - comparing <c ...>text</c> at /root[1]/d[1]/c[1]/text()[1] to <c ...>textchange</c> at /root[1]/d[1]/c[1]/text()[1]
Description: text value
*************************************************
Base Xpath: /root[1]/d[2] Value: 'd'
Test Node Xpath: null' Value: 'null' Difference ID: 22
Difference: Expected presence of child node 'd' but was 'null' - comparing <d...> at /root[1]/d[2] to at null
Description: presence of child node
*************************************************
Base Xpath: null Value: 'null'
Test Node Xpath: /root[1]/a[3]' Value: 'a' Difference ID: 22
Difference: Expected presence of child node 'null' but was 'a' - comparing at null to <a...> at /root[1]/a[3]
Description: presence of child node
Description: presence of child node
我可以使用或覆盖的任何其他方法?