我试图查询以下XML以构建一些对象,这些对象复制XML中概述的文件夹层次结构。限制查询以忽略元素后代
<ShareList>
<Title>Documantis</Title>
<Url>/sites/dev/Documantis/Forms/AllItems.aspx</Url>
<Guid>fed8f456-efa9-4fe5-8b97-46734a3040b6</Guid>
<HasUniqueScopes>False</HasUniqueScopes>
<RootFolder>/sites/dev</RootFolder>
<Children>
<ShareListItem>
<Title>First</Title>
<Url>Documantis/First</Url>
<HasUniqueRole>False</HasUniqueRole>
<IsSubFolder>False</IsSubFolder>
<PermissionMask>FullMask</PermissionMask>
<Children>
<ShareListItem>
<Title>Second</Title>
<Url>Documantis/First/Second</Url>
<HasUniqueRole>False</HasUniqueRole>
<IsSubFolder>False</IsSubFolder>
<ParentGuid>22b2a7e9-a42e-497f-aad3-8caa85f6ac6d</ParentGuid>
</ShareListItem>
</Children>
</ShareListItem>
<ShareListItem>
<Title>Folda</Title>
<Url>Documantis/Folda</Url>
<HasUniqueRole>False</HasUniqueRole>
<IsSubFolder>False</IsSubFolder>
<PermissionMask>FullMask</PermissionMask>
</ShareListItem>
</Children>
</ShareList>
我无法找到一种方法,在同一时间返回<ShareListItem>
元素之一的水平,我当前的代码返回所有ShareListItems在一个列表中没有正确地代表层次。
XmlDocument doc = new XmlDocument();
doc.LoadXml(sharepointXml);
XElement root;
using (XmlReader xr = new XmlNodeReader(doc)) { root = XElement.Load(xr); }
var result = from child in root.DescendantsAndSelf("ShareList") //.Elements("ShareList") // Descendants("ShareList")
select child;
foreach (XElement xml in result)
{
// Build ListItem from results
ShareList list = new ShareList()
{
Title = xml.Element("Title").Value,
Url = xml.Element("Url").Value,
Guid = xml.Element("Guid").Value,
HasUniqueScopes = Convert.ToBoolean(xml.Element("HasUniqueScopes").Value),
RootFolder = xml.Element("RootFolder").Value,
};
if (xml.Element("Children") != null)
{
var subResult = from child in xml.Element("Children").Descendants("ShareListItem")
select child;
foreach (XElement subXml in subResult)
{
// results here are flat and don't show depth of nodes
}
//list.Children =
}
我可以递归从URL元素推断层次的结构,但是,我已经拥有它用XML表示,所以我宁愿学习如何通过查询退货。
编辑:
这里是我最终使用
public List<ShareList> HandleLists(XElement levelRoot)
{
List<ShareList> lists = new List<ShareList>();
var results = from list in levelRoot.DescendantsAndSelf("ShareList")
select list;
foreach (var list in results)
{
var children = list.Element("Children");
if (children == null)
return null;
ShareList shareList = new ShareList()
{
Title = list.Element("Title").Value,
Url = list.Element("Url").Value,
Guid = list.Element("Guid").Value,
HasUniqueScopes = Convert.ToBoolean(list.Element("HasUniqueScopes").Value),
RootFolder = list.Element("RootFolder").Value,
// Recursively find ListItem folders
Children = HandleSubfolders(list)
};
lists.Add(shareList);
}
return lists;
}
public List<ShareListItem> HandleSubfolders(XElement levelRoot)
{
List<ShareListItem> subfolders = new List<ShareListItem>();
// All nodes deeper than current
var children = levelRoot.Element("Children");
if (children == null)
return null;
// Subfolders
var items = children.Elements("ShareListItem");
foreach (var item in items)
{
ShareListItem listItem = new ShareListItem()
{
Title = item.Element("Title").Value,
Url = item.Element("Url").Value,
HasUniqueRole = Convert.ToBoolean(item.Element("HasUniqueRole").Value),
IsSubfolder = Convert.ToBoolean(item.Element("IsSubFolder").Value),
PermissionMask = item.Element("PermissionMask").Value,
PermissionMaskName = item.Element("PermissionMaskName").Value,
// Recursively find ListItem subfolders
Children = HandleSubfolders(item)
};
// Add subfolder to Children collection
subfolders.Add(listItem);
}
return subfolders;
}
感谢您的回答,我喜欢这个例子是如何分解成小的方法,我认为这使得代码更容易维护。 – Amicable 2013-02-22 13:48:18