在 Linq 中查找两个集合中不同的子元素
我该如何为此执行 Linq 查询?
我有两个 xml 文档:doc1.xml 和 doc2.xml。如何找到 doc1 中的每个“文件”元素,其中 doc2 有一个具有完全相同的“路径”属性的“文件”元素,但 doc1 中此“文件”的任何“链接”子元素都有一个“绝对路径”属性与 doc2 中相应“file”元素中的一个或多个“absolutepath”属性不一样吗?
简单的例子:
doc1:
<doc>
<file path="c:\temp\A.xml">
<link absolutepath="c:\temp\B.xml"/>
<link absolutepath="c:\temp\C.xml"/>
</file>
<file path="c:\temp\C.xml"> <!--This should match, because it's child link absolutepath is not the same as child link absolutepath of the corresponding file with the same path in doc2-->
<link absolutepath="c:\temp\D.xml"/>
<link absolutepath="c:\temp\F.xml"/>
</file>
</doc>
doc2:
<doc>
<file path="c:\temp\A.xml">
<link absolutepath="c:\temp\B.xml"/>
<link absolutepath="c:\temp\C.xml"/>
</file>
<file path="c:\temp\C.xml">
<link absolutepath="c:\temp\D.xml"/>
<link absolutepath="c:\temp\E.xml"/>
</file>
</doc>
有什么想法吗?
编辑:编辑示例 xml 以显示每个文件元素的多个链接的含义。所以我想要的是 doc1 中的每个文件都有一个带有绝对路径的链接元素,而在 doc2 中的链接元素中找不到该绝对路径。因此,两者实际上有相同数量的链接,但绝对路径有时可能不同,这就是我想要查找并提取链接元素存在差异的那些文件。
这是我尝试修改 Jon 建议的查询,以提取多个链接,但我认为我做错了,因为之后我没有从 except 查询中得到正确的结果:
var files = from file in doc1.Descendants("file")
select new
{
file = file.Attribute("path").Value,
link = file.Elements("link").Attributes("absolutepath")
};
var oldfiles = from file in doc2.Descendants("file")
from link in file.Elements("link")
select new
{
file = file.Attribute("path").Value,
link = file.Elements("link").Attributes("absolutepath")
};
//Get the ones that are different between them
var missing = files.Except(oldfiles);
How can I do a Linq query for this?
I have two xml documents, doc1.xml, and doc2.xml. How can I find for each "file" element in doc1 where doc2 has a "file" element with the exact same "path" attribute, but any "link" child element of this "file" in doc1 has an "absolutepath" attribute that is NOT the same as one or more "absolutepath" attributes in the corresponding "file" element in doc2?
simple example:
doc1:
<doc>
<file path="c:\temp\A.xml">
<link absolutepath="c:\temp\B.xml"/>
<link absolutepath="c:\temp\C.xml"/>
</file>
<file path="c:\temp\C.xml"> <!--This should match, because it's child link absolutepath is not the same as child link absolutepath of the corresponding file with the same path in doc2-->
<link absolutepath="c:\temp\D.xml"/>
<link absolutepath="c:\temp\F.xml"/>
</file>
</doc>
doc2:
<doc>
<file path="c:\temp\A.xml">
<link absolutepath="c:\temp\B.xml"/>
<link absolutepath="c:\temp\C.xml"/>
</file>
<file path="c:\temp\C.xml">
<link absolutepath="c:\temp\D.xml"/>
<link absolutepath="c:\temp\E.xml"/>
</file>
</doc>
Any ideas?
EDIT: Edited the example xml to show what I mean by multiple links for each file element. So what I want is each file in doc1 that has a link element with an absolutepath that is not found in a link element in doc2. So there are actually the same number of links in both, but the absolutepath may differ sometimes and that's what I want to find and extract those files where there is such a difference in the link elements.
Here's my attempt to modify the query suggested by Jon, to extract multiple links, but I think I'm doing it wrong, because I don't get the correct result from the Except query afterwards:
var files = from file in doc1.Descendants("file")
select new
{
file = file.Attribute("path").Value,
link = file.Elements("link").Attributes("absolutepath")
};
var oldfiles = from file in doc2.Descendants("file")
from link in file.Elements("link")
select new
{
file = file.Attribute("path").Value,
link = file.Elements("link").Attributes("absolutepath")
};
//Get the ones that are different between them
var missing = files.Except(oldfiles);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我将从 XML 部分开始。我最初使这个变得比需要的更复杂,但我认为你可以使用:
然后如果你有
files1
和files2
(上述查询应用于每个文档)您可以这样做:编辑:要返回这些文件的链接元素,您可以使用:
再次查询文档有点可惜,但是我们开始了...
(我选择了链接元素而不是比文件元素更准确,这样你就可以得到正确的位- 您始终可以选择父元素来访问文件。)
编辑:好的,如果有多个链接元素并且您只想查找缺少元素的文件,那么从我们所得到的来看,这实际上非常容易:
Well, I would start with the XML part. I originally made this more complicated than it needs to be, but I think you can just use:
Then if you have
files1
andfiles2
(the above query applied to each document) you can just do:EDIT: To get back to the link elements for those files, you can use:
It's a bit of a shame to query the document again, but there we go...
(I've selected the link element rather than the file element so you can get to exactly the right bit - you can always choose the parent element to get to the file.)
EDIT: Okay, if there are multiple link elements and you just want to find files with missing elements, that's actually pretty easy from what we've got: