如何为此进行Linq查询?
我有两个xml文档,doc1.xml和doc2.xml。如何找到doc1中每个“file”元素,其中doc2的“file”元素具有完全相同的“path”属性,但doc1中此“文件”的任何“link”子元素都具有“absolutepath”属性,是不是与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的link元素中找不到。所以两者中实际上有相同数量的链接,但绝对路径有时会有所不同,这就是我想要找到的内容,并提取链接元素存在差异的那些文件。
这是我尝试修改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);
答案 0 :(得分:2)
好吧,我将从XML部分开始。我最初认为这比它需要的更复杂,但我认为你可以使用:
var files = from file in document.Descendants("file")
from link in file.Elements("link")
select new { file = file.Attribute("path").Value,
link = link.Attribute("absolutepath").Value };
然后,如果您有files1
和files2
(上述查询应用于每个文档),您可以这样做:
var extraFiles = files1.Except(files2);
编辑:要返回这些文件的链接元素,您可以使用:
var linkElements = from link in file.Descendants("link")
join extra in extraFiles on
new { file = link.Parent.Attribute("path").Value,
link = link.Attribute("absolutepath").Value }
equals extra
select link;
再次查询文档有点遗憾,但我们去了......
(我选择了链接元素而不是文件元素,这样你就可以得到恰到好处的位 - 你总是可以选择父元素来获取文件。)
编辑:好的,如果有多个链接元素而您只是想找到缺少元素的文件,那实际上我们已经很容易了:
var justFiles = new HashSet<string>(extraFiles.Select(x => x.file).Distinct());
var fileElements = from element in file.Descendants("file")
where justFiles.Contains((string) element.Attribute("path")
select element;