簡體   English   中英

遍歷 XML 並更改父屬性

[英]Iterate through XML and change parent properties

我目前正在以遞歸方式為 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>

我確實寫了一個后序遍歷,為葉元素添加了一個新屬性,表明它是否可見。 但是,我無法傳播此備份多個元素,因此它不是一個可行的解決方案。

我查看的另一個選項是遍歷每個節點並檢查是否有任何子節點將“列表”作為名稱。 但鑒於網站的規模,我不確定這是否可行。

遍歷層次結構的最佳方法是遞歸。

我會使用頭部遞歸來做到這一點:

public static void RemoveEmpty(XmlNode node)
{
    foreach (XmlNode child in node.SelectNodes("site"))
        RemoveEmpty(child);

    if (!node.HasChildNodes) node.ParentNode.RemoveChild(node);
}

這就是它的工作原理:

  1. 遞歸地穿過樹到葉子
  2. 通過層次結構遞歸返回根節點,在每個節點執行以下操作:
    • 如果此節點沒有子節點 - 將其刪除

根據這個算法,在每次迭代時,當前節點的所有子節點都已經被處理並且沒有空的子節點
<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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM