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