[英]Iterate through XML and change parent properties
I'm currently generating XML for a SharePoint site structure recursively (the SharePoint is just background, the issue is the XML).我目前正在以递归方式为 SharePoint 站点结构生成 XML(SharePoint 只是背景,问题是 XML)。 This gets a list of all sites and subsites.
这将获得所有站点和子站点的列表。 I then get all lists a user has access to, the structure looks like this:
然后我获取用户有权访问的所有列表,结构如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<sites>
<site title="Home" url="/">
<site title="RestApp" url="/RestApp" />
<site title="SiteMap" url="/SiteMap" />
<site title="subsite" url="/subsite">
<list title="Documents" url="/subsite" />
<site title="anothersite" url="/subsite/another" />
</site>
<site title="Template" url="/TemplatePicker" />
<site title="test" url="/test">
<site title="testing" url="/test/testing">
<site title="blah" url="/test/testing/blah">
<list title="Documents" url="/test/testing/blah" />
</site>
</site>
</site>
<site title="TestApp" url="/TestApp" />
</site>
</sites>
I now need to iterate back through the xml and remove any sites that don't have a list element as a child (or don't have an element with a list as a child).我现在需要遍历 xml 并删除所有没有作为子元素的列表元素(或者没有作为子元素的列表元素)的站点。 However, I am having trouble propagating this back to the parent nodes.
但是,我无法将其传播回父节点。 So the above xml would become:
所以上面的xml会变成:
<?xml version="1.0" encoding="UTF-8"?>
<sites>
<site title="Home" url="/">
<site title="subsite" url="/subsite">
<list title="Documents" url="/subsite" />
</site>
<site title="test" url="/test">
<site title="testing" url="/test/testing">
<site title="blah" url="/test/testing/blah">
<list title="Documents" url="/test/testing/blah" />
</site>
</site>
</site>
</site>
</sites>
I did write a post-order traversel that adds a new attribute to the leaf elements that says if it's visible.我确实写了一个后序遍历,为叶元素添加了一个新属性,表明它是否可见。 However, I am unable to propogate this backup more than one element so it isn't a viable solution.
但是,我无法传播此备份多个元素,因此它不是一个可行的解决方案。
The other option I have looked at is going through each node and checking if any of the children have 'list' as a name.我查看的另一个选项是遍历每个节点并检查是否有任何子节点将“列表”作为名称。 But I'm not sure if this is viable given the size of the site.
但鉴于网站的规模,我不确定这是否可行。
The best way to iterate through a hierarchical structure is a recursion.遍历层次结构的最佳方法是递归。
I would do this this using head recursion :我会使用头部递归来做到这一点:
public static void RemoveEmpty(XmlNode node)
{
foreach (XmlNode child in node.SelectNodes("site"))
RemoveEmpty(child);
if (!node.HasChildNodes) node.ParentNode.RemoveChild(node);
}
That's how it works:这就是它的工作原理:
According to this algorithm, at every iteration all of current node's child nodes are already processed and don't have empty child notes .根据这个算法,在每次迭代时,当前节点的所有子节点都已经被处理并且没有空的子节点。
Non- <site>
tags are ignored and not being checked and removed but they are counted during check for having child nodes.非
<site>
标签将被忽略,不会被检查和删除,但在检查是否有子节点时会对其进行计数。
Now you only need to run this function from your root node.现在你只需要从你的根节点运行这个函数。
XmlDocument document = new XmlDocument();
document.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?><sites> <site title=\"Home\" url=\"/\"> <site title=\"RestApp\" url=\"/RestApp\" /> <site title=\"SiteMap\" url=\"/SiteMap\" /> <site title=\"subsite\" url=\"/subsite\"> <list title=\"Documents\" url=\"/subsite\" /> <site title=\"anothersite\" url=\"/subsite/another\" /> </site> <site title=\"Template\" url=\"/TemplatePicker\" /> <site title=\"test\" url=\"/test\"> <site title=\"testing\" url=\"/test/testing\"> <site title=\"blah\" url=\"/test/testing/blah\"> <list title=\"Documents\" url=\"/test/testing/blah\" /> </site> </site> </site> <site title=\"TestApp\" url=\"/TestApp\" /> </site></sites>");
RemoveEmpty(document.SelectSingleNode("sites"));
Console.WriteLine(document.OuterXml);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.