![](/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.