我有两个XML文件(我称之为A和B),它们包含重复的记录,但其中一个文件可能有额外的记录,或者可能少一些。我需要编写一些Linq代码来比较两个文件,告诉我文件“A”是否有不在文件“B”中的记录。我还需要反向并选择文件“B”中但不在文件“A”中的记录。每个文件中的XML看起来类似于:
<importJob>
<entities>
<entity id="7eaab021-1c05-4385-b820-50aa619c9a99" >
<field name="RuleTypeId" value="a29b9bce-d1f5-4c11-879f-f1a572b6ff0a" />
<field name="Name" value="Group1" />
<field name="Notes" />
<field name="EntityId" value="14B03381-C09C-4B69-A749-F33A4B3F0305" />
<field name="Selector" />
</entity>
<entity id="69cd0eab-d10d-46fb-b1a3-018fd9d6aa97" >
<field name="RuleTypeId" value="a29b9bce-d1f5-4c11-879f-f1a572b6ff0a" />
<field name="Name" value="Group2" />
<field name="Notes" />
<field name="EntityId" value="1eaab021-1c05-4385-b820-50aa619c9a99" />
<field name="Selector" />
</entity>
</entities>
</importJob>
需要对实体“id”属性进行比较。如果两个具有相同id的文件中都存在记录,则表示匹配。两者的“字段”值可能不同,但我仍然希望将其视为匹配。
假设上面的XML在文件“A”中并且以下XML在文件“B”中,我希望输出说记录“69cd0eab-d10d-46fb-b1a3-018fd9d6aa97”在文件“A”中但是不在文件“B”中。请注意,尽管记录“7eaab021-1c05-4385-b820-50aa619c9a99”的内容都不同,但id匹配,因此不应将其标记为不在文件“B”中
<importJob>
<entities>
<entity id="7eaab021-1c05-4385-b820-50aa619c9a99" >
<field name="RuleTypeId" value="0eaab021-1c05-4385-b820-50aa619c9a99" />
<field name="Name" value="Group9" />
<field name="Notes" />
<field name="EntityId" value="05e3b0d2-6f15-4c3e-b737-01ee5b1b1ae1" />
<field name="Selector" value="1" />
</entity>
<entity id=" 96AA845C-2848-49E3-8BA6-F50F34F66749" >
<field name="RuleTypeId" value="a29b9bce-d1f5-4c11-879f-f1a572b6ff0a" />
<field name="Name" value="Group10" />
<field name="Notes" />
<field name="EntityId" value=" 53431D25-F7C4-4A8A-8E12-43F4D29BF46A" />
<field name="Selector" />
</entity>
</entities>
</importJob>
我开始使用这个Linq语句,但它查看整个节点。我尝试添加一个属性引用,但它不会构建。有人帮我解决这个问题吗?
var diff = fileA.Descendants("entity").Except(fileB.Descendants("entity"), new XNodeEqualityComparer());
答案 0 :(得分:2)
首先 - 从两个文件中选择实体ID。您可以在投影查询时将id属性强制转换为Guid
。这将返回guids的集合:
var idsA = xdocA.Descendants("entity").Select(e => (Guid)e.Attribute("id"));
var idsB = xdocB.Descendants("entity").Select(e => (Guid)e.Attribute("id"));
然后使用Enumerable.Intersect
和Enumerable.Except
查找仅存在于第二序列中的序列和ID中的公共ID:
IEnumerable<Guid> inBothFiles = idsA.Intersect(idsB);
IEnumerable<Guid> onlyInFileB = idsB.Except(idsA);
答案 1 :(得分:0)
假设您将这两个文件都作为xDoc:
var aIds = fileA.Descendants("entity").Select(x=> x.Attribute("id").Value()).ToList();
var bIds = fileb.Descendants("entity").Select(x=> x.Attribute("id").Value()).ToList();
var noMatches = aIds.Select(x=> !bIds.Contains(x).Tolist();
noMatches.AddRange(bIds.Select(x=> !aIds.Contains(x).Tolist());
这将为您提供不匹配的ID列表,修改一下您可以得到您想要的(例如,选择一个新对象,即文件名和ID的NV对)。