Sorry if this question is very basic, but I haven't worked with XML very much, and this is my first time working with LINQ to XML...
开发者_如何学GoI have an XML sitemap that is structured like a directory tree:
<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>
In this way, every file will inherit security from its parent folder (or grandparent folder, etc, depending upon how far up the tree the <security></security>
is located.
I want to be able to, given a file's GUID, select that file with LINQ, and gather all of the roles associated with the security that file has inherited.
This is what I have so far, but it is a very rough attempt, and is not complete:
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. The sitemap file is located within the same directory as the class in which this code is written
It looks like you want to walk up the folder ancestor chain and accumulate the roles you find along the way. You can do that with the aptly-named Ancestors() and SelectMany() methods:
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]);
}));
EDIT: Changed element capitalization to match the updated question.
EDIT 2: The code above was mistakenly feeding a null
item to SelectMany()
(which is far less indulgent than XElement.Add()
in this regard), and this resulted in a NullPointerException
. It has been updated to return an empty XElement
array instead.
Try this (I usually do Method syntax but you should be able to convert to query syntax)
XElement currentFile = new XElement("File",
sitemap.Descendants("file").Where(
file => file.Attribute("GUID").Value.Equals(guid)).Select(
file => file.Parent.Element("security").Elements("role")));
Here currentFile should have
<File>
<role>Admin</role>
</File>
精彩评论