![](/img/trans.png)
[英]How do you use linq to xml to find matching nodes in two different xml files
[英]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.