2015-07-01 4 views
2

Я в настоящее время рекурсивно создаю XML для структуры сайта SharePoint (SharePoint - это просто фон, проблема в XML). Это получает список всех сайтов и подсайтов. тогда я получаю все списки пользователь имеет доступ, структура выглядит следующим образом:Итерация через 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> 

я написать traversel пост-заказ, который добавляет новый атрибут для листовых элементов, который говорит, если она видна. Тем не менее, я не могу распространять эту резервную копию более чем на один элемент, поэтому это не жизнеспособное решение.

Другой вариант, который я просмотрел, проходит через каждый узел и проверяет, есть ли у какого-либо из них «список» в качестве имени. Но я не уверен, что это жизнеспособно, учитывая размер сайта.

ответ

2

Лучший способ перебора иерархической структуры - это рекурсия.

Я хотел бы сделать это это с помощью головы рекурсии:

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); 
Смежные вопросы