LINQ&;XNode.DeepEquals运行两次比较

本文关键字:两次 比较 运行 amp XNode DeepEquals LINQ | 更新日期: 2023-09-27 17:58:36

我正在使用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在我的列表中为每个差异提供两个元素吗?确认这一点可以让我通过排除每一个差异的第二个元素来继续工作,但显然我不能这样做,除非它总是存在。

LINQ&;XNode.DeepEquals运行两次比较

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