问题
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...
I 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
回答1:
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.
回答2:
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>
来源:https://stackoverflow.com/questions/6821443/linq-to-xml-querying-for-sibling-elements