我目前正在递归地为 SharePoint 网站结构生成 XML(SharePoint 只是背景,问题是 XML)。这将获取所有站点和子站点的列表。然后我获取用户有权访问的所有列表,结构如下所示:
<?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>
我现在需要迭代 xml 并删除任何没有列表元素作为子元素(或者没有包含列表元素作为子元素)的网站。但是,我无法将其传播回父节点。所以上面的 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>
我确实编写了一个后序遍历,它向叶元素添加了一个新属性,表示它是否可见。但是,我无法将此备份传播到多个元素,因此它不是一个可行的解决方案。
我研究过的另一个选项是遍历每个节点并检查是否有任何子节点的名称为“list”。但考虑到网站的规模,我不确定这是否可行。
最佳答案
迭代层次结构的最佳方法是递归。
我会使用头递归来做到这一点:
public static void RemoveEmpty(XmlNode node)
{
foreach (XmlNode child in node.SelectNodes("site"))
RemoveEmpty(child);
if (!node.HasChildNodes) node.ParentNode.RemoveChild(node);
}
这就是它的工作原理:
- 递归地遍历树直至叶子
- 通过层次结构递归返回根,在每个节点执行以下操作:
- 如果该节点没有子节点 - 删除它
根据此算法,在每次迭代时当前节点的所有子节点都已处理完毕,并且没有空子注释。
非<site>
标签将被忽略,不会被检查和删除,但在检查是否有子节点时会对其进行计数。
现在您只需从根节点运行此函数即可。
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);
关于c# - 遍历 XML 并更改父属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31151800/