Skip to content

Commit

Permalink
port xmlunit/#236
Browse files Browse the repository at this point in the history
  • Loading branch information
bodewig committed Dec 16, 2021
1 parent 82ca1c0 commit 4553a26
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
4 changes: 4 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## XMLUnit.NET 2.9.1 - /not released, yet/

* improved comparison performance for documents with many siblings
based on a suggestion by [@gerpres](https://github.com/gerpres) made
in Java Issue [xmlunit/#236](https://github.com/xmlunit/xmlunit/issues/236)

* added a new `FullDescription` method to `Diff` that provides a
string-representation of all differences - not just the first one
like `ToString` does.
Expand Down
36 changes: 25 additions & 11 deletions src/main/net-core/Diff/DOMDifferenceEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -472,16 +472,22 @@ private ComparisonState CompareNodeLists(IEnumerable<XmlNode> allControlChildren
IList<XmlNode> testListForXpath = new List<XmlNode>(allTestChildren);
IList<XmlNode> controlList = new List<XmlNode>(controlSeq);
IList<XmlNode> testList = new List<XmlNode>(testSeq);

IDictionary<XmlNode, int> controlListForXpathIndex = Index(controlListForXpath);
IDictionary<XmlNode, int> testListForXpathIndex = Index(testListForXpath);
IDictionary<XmlNode, int> controlListIndex = Index(controlList);
IDictionary<XmlNode, int> testListIndex = Index(testList);

ICollection<XmlNode> seen = new HashSet<XmlNode>();
foreach (KeyValuePair<XmlNode, XmlNode> pair in matches) {
XmlNode control = pair.Key;
seen.Add(control);
XmlNode test = pair.Value;
seen.Add(test);
int controlIndexForXpath = controlListForXpath.IndexOf(control);
int testIndexForXpath = testListForXpath.IndexOf(test);
int controlIndex = controlList.IndexOf(control);
int testIndex = testList.IndexOf(test);
int controlIndexForXpath = controlListForXpathIndex[control];
int testIndexForXpath = testListForXpathIndex[test];
int controlIndex = controlListIndex[control];
int testIndex = testListIndex[test];
controlContext.NavigateToChild(controlIndexForXpath);
testContext.NavigateToChild(testIndexForXpath);
try {
Expand All @@ -500,13 +506,13 @@ private ComparisonState CompareNodeLists(IEnumerable<XmlNode> allControlChildren
}

return chain
.AndThen(UnmatchedControlNodes(controlListForXpath, controlList, controlContext,
.AndThen(UnmatchedControlNodes(controlListForXpathIndex, controlList, controlContext,
seen, testContext))
.AndThen(UnmatchedTestNodes(testListForXpath, testList, testContext, seen,
controlContext));
.AndThen(UnmatchedTestNodes(testListForXpathIndex, testList, testContext,
seen, controlContext));
}

private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListForXpath,
private Func<ComparisonState> UnmatchedControlNodes(IDictionary<XmlNode, int> controlListForXpathIndex,
IList<XmlNode> controlList,
XPathContext controlContext,
ICollection<XmlNode> seen,
Expand All @@ -517,7 +523,7 @@ private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListFo
for (int i = 0; i < controlSize; i++) {
if (!seen.Contains(controlList[i])) {
controlContext
.NavigateToChild(controlListForXpath.IndexOf(controlList[i]));
.NavigateToChild(controlListForXpathIndex[controlList[i]]);
try {
chain = chain
.AndThen(new Comparison(ComparisonType.CHILD_LOOKUP,
Expand All @@ -536,7 +542,7 @@ private Func<ComparisonState> UnmatchedControlNodes(IList<XmlNode> controlListFo
};
}

private Func<ComparisonState> UnmatchedTestNodes(IList<XmlNode> testListForXpath,
private Func<ComparisonState> UnmatchedTestNodes(IDictionary<XmlNode, int> testListForXpathIndex,
IList<XmlNode> testList,
XPathContext testContext,
ICollection<XmlNode> seen,
Expand All @@ -546,7 +552,7 @@ private Func<ComparisonState> UnmatchedTestNodes(IList<XmlNode> testListForXpath
int testSize = testList.Count;
for (int i = 0; i < testSize; i++) {
if (!seen.Contains(testList[i])) {
testContext.NavigateToChild(testListForXpath.IndexOf(testList[i]));
testContext.NavigateToChild(testListForXpathIndex[testList[i]]);
try {
chain = chain
.AndThen(new Comparison(ComparisonType.CHILD_LOOKUP,
Expand Down Expand Up @@ -737,5 +743,13 @@ private static XmlAttribute FindMatchingAttr(IList<XmlAttribute> attrs,
return null;
}

private static IDictionary<XmlNode, int> Index(IList<XmlNode> nodes) {
IDictionary<XmlNode, int> indices = new Dictionary<XmlNode, int>();
int idx = 0;
foreach (XmlNode n in nodes) {
indices[n] = idx++;
}
return indices;
}
}
}

0 comments on commit 4553a26

Please sign in to comment.