diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index b3bc6a5..5684297 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -39,6 +39,22 @@
`DiffBuilder` and `CompareConstraint`.
Issue similar to [xmlunit/#119](https://github.com/xmlunit/xmlunit/issues/119).
+* the configured `NodeFilter` is now applied before comparing
+ `XmlDocumentType` nodes.
+
+ This change breaks backwards compatibility as the old behavior was
+ to ignore `XmlDocumentType` when counting the children of the
+ `XmlDocument` node but not when actually comparing the
+ `XmlDocumentType`. Prior to this change if one document had a document
+ type declaration but the other didn't, a `HAS_DOCTYPE_DECLARATION`
+ difference was detected, this will no longer be the case now. If you
+ want to detect this difference, you need to use a more lenient
+ `NodeFilter` than `NodeFilters.Default`
+ (i.e. `NodeFilters.AcceptAll`) but then you will see an additional
+ `CHILD_NODELIST_LENGTH` difference.
+
+ Issue [#26](https://github.com/xmlunit/xmlunit.net/issues/26).
+
## XMLUnit.NET 2.5.1 - /Released 2017-10-20/
* elements that only differed in namespace prefix resulted in a false
diff --git a/src/main/net-core/Diff/ComparisonType.cs b/src/main/net-core/Diff/ComparisonType.cs
index 137413f..f3d6167 100644
--- a/src/main/net-core/Diff/ComparisonType.cs
+++ b/src/main/net-core/Diff/ComparisonType.cs
@@ -35,6 +35,14 @@ public enum ComparisonType {
///
/// Do both documents have a DOCTYPE (or neither of each)?
///
+ ///
+ ///
+ /// This difference is most likely masked by a
+ /// CHILD_NODELIST_LENGTH difference as the number of children
+ /// of the document node is tested before the presence of the
+ /// document type declaration.
+ ///
+ ///
HAS_DOCTYPE_DECLARATION,
///
/// If the documents both have DOCTYPEs, compare the names.
@@ -127,4 +135,4 @@ public enum ComparisonType {
///
ATTR_NAME_LOOKUP,
}
-}
\ No newline at end of file
+}
diff --git a/src/main/net-core/Diff/DOMDifferenceEngine.cs b/src/main/net-core/Diff/DOMDifferenceEngine.cs
index a420c9d..a72c8ee 100644
--- a/src/main/net-core/Diff/DOMDifferenceEngine.cs
+++ b/src/main/net-core/Diff/DOMDifferenceEngine.cs
@@ -200,8 +200,8 @@ private ComparisonState CompareDocuments(XmlDocument control,
XPathContext controlContext,
XmlDocument test,
XPathContext testContext) {
- XmlDocumentType controlDt = control.DocumentType;
- XmlDocumentType testDt = test.DocumentType;
+ XmlDocumentType controlDt = FilterNode(control.DocumentType);
+ XmlDocumentType testDt = FilterNode(test.DocumentType);
return Compare(new Comparison(ComparisonType.HAS_DOCTYPE_DECLARATION,
control, GetXPath(controlContext),
@@ -217,6 +217,10 @@ private ComparisonState CompareDocuments(XmlDocument control,
testContext));
}
+ private T FilterNode(T n) where T : XmlNode {
+ return n != null && NodeFilter(n) ? n : null;
+ }
+
///
/// Compares properties of the doctype declaration.
///
diff --git a/src/main/net-core/Diff/DifferenceEvaluators.cs b/src/main/net-core/Diff/DifferenceEvaluators.cs
index 56c1ef3..ef5a6a3 100644
--- a/src/main/net-core/Diff/DifferenceEvaluators.cs
+++ b/src/main/net-core/Diff/DifferenceEvaluators.cs
@@ -159,9 +159,14 @@ public static DifferenceEvaluator IgnorePrologDifferences() {
/// declaration that are part of the XML prolog.
///
///
- ///
Here "ignore" means return {@code ComparisonResult.EQUAL}.
- ///
- ///
+ ///
+ /// Here "ignore" means return ComparisonResult.EQUAL.
+ ///
+ ///
+ /// In general different doctype declarations will be ignored
+ /// because of NodeFilters.Default, so if you want to detect
+ /// these differences you need to pick a different NodeFilter.
+ ///
///
/// since XMLUnit 2.1.0
///
@@ -211,4 +216,4 @@ private static bool IsSequenceOfRootElement(Comparison comparison) {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/net-core/Diff/NodeFilters.cs b/src/main/net-core/Diff/NodeFilters.cs
index 0b8958b..d2179eb 100644
--- a/src/main/net-core/Diff/NodeFilters.cs
+++ b/src/main/net-core/Diff/NodeFilters.cs
@@ -23,9 +23,27 @@ public static class NodeFilters {
///
/// Suppresses document-type and XML declaration nodes.
///
+ ///
+ ///
+ /// This is the default used by AbstractDifferenceEngine and
+ /// thus DOMDifferenceEngine.
+ ///
+ ///
public static bool Default(XmlNode n) {
return n.NodeType != XmlNodeType.DocumentType
&& n.NodeType != XmlNodeType.XmlDeclaration;
}
+
+ ///
+ /// Suppresses document-type and XML declaration nodes.
+ ///
+ ///
+ ///
+ /// since XMLUnit 2.6.0
+ ///
+ ///
+ public static bool AcceptAll(XmlNode n) {
+ return true;
+ }
}
}
diff --git a/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs b/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs
index cd11b7e..68eda38 100644
--- a/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs
+++ b/src/tests/net-core/Diff/DOMDifferenceEngineTest.cs
@@ -362,6 +362,12 @@ public void CompareDocuments() {
d.DifferenceListener += ex.ComparisonPerformed;
d.DifferenceEvaluator = delegate(Comparison comparison,
ComparisonResult outcome) {
+ if (comparison.Type == ComparisonType.CHILD_NODELIST_LENGTH) {
+ Assert.AreEqual(ComparisonResult.DIFFERENT, outcome);
+ // downgrade so we get to see the
+ // HAS_DOCTYPE_DECLARATION difference
+ return ComparisonResult.EQUAL;
+ }
if (comparison.Type == ComparisonType.HAS_DOCTYPE_DECLARATION) {
Assert.AreEqual(ComparisonResult.DIFFERENT, outcome);
return ComparisonResult.DIFFERENT;
@@ -370,6 +376,7 @@ public void CompareDocuments() {
return ComparisonResult.EQUAL;
};
d.ComparisonController = ComparisonControllers.StopWhenDifferent;
+ d.NodeFilter = NodeFilters.AcceptAll;
XmlDocument d1, d2;
@@ -452,6 +459,30 @@ public void CompareDocuments() {
Assert.AreEqual(1, ex.invoked);
}
+ [Test]
+ public void NodeFilterAppliesToDocTypes() {
+ DOMDifferenceEngine d = new DOMDifferenceEngine();
+ DiffExpecter ex =
+ new DiffExpecter(ComparisonType.HAS_DOCTYPE_DECLARATION);
+ d.DifferenceListener += ex.ComparisonPerformed;
+ d.ComparisonController = ComparisonControllers.StopWhenDifferent;
+
+ XmlDocument d1, d2;
+
+ d1 = Org.XmlUnit.Util.Convert
+ .ToDocument(InputBuilder.FromString("").Build());
+ d2 = new XmlDocument();
+ d2.LoadXml(""
+ + "");
+ Assert.AreEqual(Wrap(ComparisonResult.EQUAL),
+ d.CompareNodes(d1, new XPathContext(),
+ d2, new XPathContext()));
+ Assert.AreEqual(0, ex.invoked);
+ }
+
[Test]
public void CompareDocTypes() {
DOMDifferenceEngine d = new DOMDifferenceEngine();