Question

I'm using LINQ to compare two XML documents. If a difference is found between two elements I add those nodes to a list which I use to generate a report of differences.

The 'problem' is that if a difference is found it is added to the list twice.

For example, given two simple XML docs:

Expected:

<Parsed_Data>
  <IntentCount>0</IntentCount>
  .
  .
  .
</Parsed_Data>

Actual:

<Parsed_Data>
  <IntentCount>1</IntentCount>
  .
  .
  .
</Parsed_Data>

And using this code to compare nodes and add them to a list if they're different:

The Node class contains two XNodes, one for expected and one for actual.

var expectedNodesRoot = from desc in expected.Descendants("root") 
                        select desc;

var actualNodesRoot = from desc in actual.Descendants("root")
                                select desc;

IEnumerable<XNode> expectedNodes =
               from node in expectedNodesRoot.Elements("Parsed_Data").DescendantNodes()
                select node;

IEnumerable<XNode> actualNodes =
                from node in actualNodesRoot.Elements("Parsed_Data").DescendantNodes()
                select node;

 List<Node> diffList = new List<Node>();
 IEnumerator e = expectedNodes.GetEnumerator();
 IEnumerator a = actualNodes.GetEnumerator();

 while (e.MoveNext() && a.MoveNext())
 {
   var xe = e.Current as XNode;
   var xa = a.Current as XNode;

   if (!XNode.DeepEquals(xe, xa))
   {
     diffList.Add(new Node(xe, xa));
   }
 }

For one difference, this gives me two elements in my diffList:

expectedNode: "<IntentCount>1</IntentCount>"
actualNode: "<IntentCount>0</IntentCount>"

expectedNode = "{1}"
actualNode = "{0}"

It seems that DeepEquals compares first the element and then the values. My question is, is there anything in my code that could be causing the duplicates or is this a feature of DeepEquals that I can't do anything about?

I've run tests to see if this always happens and that seems to be the case. So a follow up question would be: Can I count on XNode.DeepEquals to always give me two elements per difference in my List? Confirming this would allow me to continue the work by excluding the second element for each difference, but obviously I can't do that unless it'll always be present.

Était-ce utile?

La solution

The text in an XML document is exposed as an XText (which is an XNode). By going through the descendant nodes, you are going through elements and text. You probably should be going through elements with no child elements.

var expectedElements = expected.Descendants("root")
    .Elements("Parsed_Data")
    .Descendants()
    .Where(d => !d.HasElements);
var actualElements = actual.Descendants("root")
    .Elements("Parsed_Data")
    .Descendants()
    .Where(d => !d.HasElements);
var diffList = expectedElements.Zip(actualElements, (e, a) => new Node(e, a))
    .Where(n => !XNode.DeepEquals(n.Expected, n.Actual))
    .ToList();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top