LINQ & XNode.DeepEquals выполняет сравнения дважды?

Я использую LINQ для сравнения двух документов XML. Если между двумя элементами обнаруживается разница, я добавляю эти узлы в список, который я использую для создания отчета о различиях.

Проблема в том, что если разница обнаружена, она добавляется в список дважды.

Например, даны два простых документа XML:

Ожидаемое:

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

Актуально:

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

И используя этот код для сравнения узлов и добавления их в список, если они разные:

Класс Node содержит два XNodes, один для ожидаемого и один для фактического.

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));
   }
 }

Для одного различия это дает мне два элемента в моем diffList:

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

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

Кажется, что DeepEquals сравнивает сначала элемент, а затем значения. У меня вопрос, есть ли в моем коде что-то, что может вызывать дубликаты, или это особенность DeepEquals, с которой я ничего не могу поделать?

Я запустил тесты, чтобы увидеть, всегда ли это происходит, и, похоже, это так. Таким образом, последующим вопросом будет: Могу ли я рассчитывать на XNode.DeepEquals, чтобы всегда давать мне два элемента на разницу в моем Списке? Подтверждение этого позволило бы мне продолжить работу, исключив второй элемент для каждого различия, но, очевидно, я не смогу сделать это, если он не будет присутствовать всегда.

1 ответ

Решение

Текст в документе XML отображается как XText (который является XNode). Проходя через узлы-потомки, вы проходите через элементы и текст. Вы, вероятно, должны проходить элементы без дочерних элементов.

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();
Другие вопросы по тегам