繁体   English   中英

如何检查包含在不同 XML 文件中的 XML 节点是否相等?

[英]How to check XML nodes contained in different XML files for equality?

我有两个 XML 文件(文件 A 和文件 B,其中文件 A 是文件 B 的子集),我使用System.Xml.XmlDocument.LoadXml(fileName)方法读取它们。

然后我使用System.Xml.XmlNode.SelectNodes(nodeName)在这些文件中选择节点我需要比较文件 A 中每个选定的 xml 节点是相等的还是文件 B 中同一节点的子集。还需要检查文件 A 中任何节点中包含的子节点的顺序与文件 B 中该节点中包含的相同子节点的顺序相同。

例如,

文件A

<rootNodeA>
 <elementA>
  <subelementA>content</subElementA>
  <subelementB>content</subElementB>
  <subelementB>content</subElementC>
  <subelementB>content</subElementD>
 </elementA>
 <elementB>
  <subelementA>content</subElementA>
  <subelementB>content</subElementB>
 </elementB>
</rootNodeA>

文件B

<rootNodeB>
 <elementA>
  <subelementB>content</subElementB>
  <subelementD>content</subElementD>
 </elementA>
 <elementB>
  <subelementA>content</subElementA>
 </elementB>
</rootNodeB>

如您所见,fileB 是 fileA 的子集。 我需要检查文件 B 的elementA节点是否相等或文件 A 中相同elementA节点的子集。这对于子节点( subElementA等)以及节点/子节点的内容也应该如此。

此外,如果您在文件 A 中看到elementA ,则有 4 个子元素,其顺序为 A、B、C、D。 对于相同elementA在FILEB,有2子元素的顺序A,d。 这个顺序即A在D之前与文件A中的顺序相同,也需要检查这一点。

我的想法是计算节点的哈希值,然后比较它们,但不确定这如何或是否能满足目的。

编辑:我到目前为止的代码,

    HashSet<XmlElement> hashA = new HashSet<XmlElement>();
    HashSet<XmlElement> hashB = new HashSet<XmlElement>();

                foreach (XmlElement node in nodeList)
                {
                    hashA.Add(node);
                }
                foreach(XmlElement node in masterNodeList)
                {
                    hashB.Add(node);
                }
                isSubset = new HashSet<XmlElement>(hashA).IsSubsetOf(hashB);
            return isSubset;

这听起来像是一个简单的递归函数。

没有检查它是否真的有效,但应该这样做:

public static bool isSubset(XmlElement source, XmlElement target)
    {
        if (!target.HasChildNodes)
        {
            if (source.HasChildNodes) // surly not same.
                return false;
            return string.Equals(source.Value, target.Value); // equalize values.
        }

        var sourceChildren = source.ChildNodes.OfType<XmlElement>().ToArray(); // list all child tags in source (by order)
        var currentSearchIndex = 0; // where are we searching from (where have we found our match)

        foreach (var targetChild in target.ChildNodes.OfType<XmlElement>())
        {
            var findIndex = Array.FindIndex(sourceChildren, currentSearchIndex, el => el.Name == targetChild.Name);
            if (findIndex == -1)
                return false; // not found in source, therefore not a subset.

            if (!isSubset(sourceChildren[findIndex], targetChild))
                return false; // if the child is not a subset, then parent isn't too.

            currentSearchIndex = findIndex; // increment our search index so we won't match nodes that already passed.
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM