很抱歉,如果这个问题非常基础,但我没有使用过XML,这是我第一次使用LINQ to XML ...
我有一个XML站点地图,其结构类似于目录树:
<Site>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<Folder name="FolderName">
<Security>
<Role>Admin</role>
</Security>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<Folder name="subFoler">
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
<Folder>
<File GUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">FileName</file>
</Folder>
</Folder>
</Folder>
</Site>
通过这种方式,每个文件都将从其父文件夹(或祖父文件夹等)继承安全性,具体取决于<security></security>
所在的树的距离。
我希望能够在给定文件的GUID的情况下,使用LINQ选择该文件,并收集与文件已继承的安全性相关联的所有角色。
这是我到目前为止所做的,但这是一次非常艰难的尝试,而且还不完整:
XDocument sitemap = XDocument.Load(@"\sitemap.xml");
XElement currentFile = new XElement("File",
from file in sitemap.Elements("File")
where file.Element("GUID").Equals(guid)
select file.Parent.Element("security").Elements("role"));
PS。站点地图文件与编写此代码的类位于同一目录中
答案 0 :(得分:2)
看起来你想走上文件夹祖先链并累积你沿途找到的角色。您可以使用恰当命名的Ancestors()和SelectMany()方法执行此操作:
XElement fileFromMap = sitemap.Descendants("File").Where(
file => file.Attribute("GUID").Value == guid.ToString("D")).Single();
XElement currentFile = new XElement("File",
fileFromMap.Value,
fileFromMap.Ancestors("Folder").SelectMany(
folder => {
XElement security = folder.Element("Security");
return (security != null
? security.Elements("Role") : new XElement[0]);
}));
编辑:更改了元素大小以匹配更新后的问题。
编辑2:上面的代码错误地将null
项目投放到SelectMany()
(在这方面远不如XElement.Add()
放纵),并且这resulted in a NullPointerException
。它已更新为返回空XElement
数组。
答案 1 :(得分:0)
试试这个(我通常做方法语法,但你应该能够转换为查询语法)
XElement currentFile = new XElement("File",
sitemap.Descendants("file").Where(
file => file.Attribute("GUID").Value.Equals(guid)).Select(
file => file.Parent.Element("security").Elements("role")));
这里currentFile应该有
<File>
<role>Admin</role>
</File>