Как я могу найти все подузлы в моем XML - PullRequest
3 голосов
/ 20 февраля 2012

Я пытаюсь получить все подстраницы в моем примере ниже.XML выглядит следующим образом (простой макет)

<?xml version="1.0"?>

<main> 
  <group  title="Server Tools" enabled="True">
    <page title="Server Tools" pageId="1" subtitle="Tools for servers" enabled="True">
      <subpage title="Name-1" pageId="2" subtitle="" enabled="True">        
        <subpage title="Name-2" pageId="3" subtitle="" enabled="True">
            <subpage title="Name-3" pageId="4" subtitle="" enabled="True">
                <subpage title="Name-4" pageId="5" subtitle="" enabled="True">                  
                </subpage>
            </subpage>
        </subpage>
      </subpage>
    </page> 
  </group>
</main>

Я пытался создать следующее, но он находит только первую «подстраницу».

XmlDocument doc = new XmlDocument();
doc.Load(path + @"\config.xml");

XmlNodeList groups = doc.SelectNodes("main/group");
foreach (XmlNode group in groups)
{
    String groupTitle = group.Attributes["title"].InnerText;
    String groupEnabled = group.Attributes["enabled"].InnerText;
    maxResults = Convert.ToInt32(group.Attributes["maxResults"].InnerText);

    if (groupEnabled == "True")
    {
       firstGroup.Title = groupTitle;
       XmlNodeList pages = group.SelectNodes("page");

       foreach (XmlNode page in pages)
       {
          String pageTitle = page.Attributes["title"].InnerText;
          int pageId = Convert.ToInt32(page.Attributes["pageId"].InnerText);
          String subtitle = page.Attributes["subtitle"].InnerText;
          String pageEnabled = page.Attributes["enabled"].InnerText;

          if(pageEnabled == "True")
          {
             firstGroup.Items.Add(new PageItem(pageId, pageTitle, subtitle));
             pageList.Add(pageId);
             XmlNodeList subpages = page.SelectNodes("subpage");

             foreach (XmlNode subpage in subpages)
             {
                string subpageTitle = subpage.Attributes["title"].InnerText;
                int subpageId = Convert.ToInt32(subpage.Attributes["pageId"].InnerText);
                String subpageSubtitle = subpage.Attributes["subtitle"].InnerText;
                String subpageEnabled = subpage.Attributes["enabled"].InnerText;

                if (subpageEnabled == "True")
                {
                   subpageDic.Add(subpageId, new Tuple<int, string, string>(pageId, subpageTitle, subpageSubtitle));
                }
             }
          }
       }
    }
 }

Что я делаю неправильно?Я просто хочу пройти по всем подстраницам ниже подстраницы и получить доступные атрибуты.

Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 20 февраля 2012

Возможно, попробуйте использовать XPATH:

XmlDocument document = ...;
var nodes = document.SelectNodes("//subpage");

nodes будет содержать эту коллекцию:

<subpage title="Name-1" pageId="2" subtitle="" enabled="True">        
    <subpage title="Name-2" pageId="3" subtitle="" enabled="True">
        <subpage title="Name-3" pageId="4" subtitle="" enabled="True">
                <subpage title="Name-4" pageId="5" subtitle="" enabled="True">                  
                </subpage>
            </subpage>
        </subpage>
    </subpage>
<subpage title="Name-2" pageId="3" subtitle="" enabled="True">
    <subpage title="Name-3" pageId="4" subtitle="" enabled="True">
    <subpage title="Name-4" pageId="5" subtitle="" enabled="True">                  
</subpage>

Теперь для каждого узла в узлах выберите рекурсивно //subpage.

EDIT:

XPATH - мощный инструмент.Попробуйте с этим xpath: //../subpage.Результат:

<subpage title="Name-1" pageId="2" subtitle="" enabled="True">        
        <subpage title="Name-2" pageId="3" subtitle="" enabled="True">
            <subpage title="Name-3" pageId="4" subtitle="" enabled="True">
                <subpage title="Name-4" pageId="5" subtitle="" enabled="True">                  
                </subpage>
            </subpage>
        </subpage>
    </subpage>
-----------------------
<subpage title="Name-2" pageId="3" subtitle="" enabled="True">
    <subpage title="Name-3" pageId="4" subtitle="" enabled="True">
        <subpage title="Name-4" pageId="5" subtitle="" enabled="True">                  
        </subpage>
    </subpage>
</subpage>
-----------------------
<subpage title="Name-3" pageId="4" subtitle="" enabled="True">
    <subpage title="Name-4" pageId="5" subtitle="" enabled="True">                  
    </subpage>
</subpage>
-----------------------
<subpage title="Name-4" pageId="5" subtitle="" enabled="True">
</subpage>
1 голос
/ 20 февраля 2012

Ваша проблема здесь :

XmlNodeList subpages = page.SelectNodes("subpage"); 

subpages содержит только дочерние элементы subpage элемента, содержащегося в page.

ОднакоВы хотите, чтобы все потомки из page.

Решение :

Замените приведенную выше строку этой :

XmlNodeList subpages = page.SelectNodes(".//subpage"); 

Переменная subpages теперь содержит все subpage потомков текущего узла page.

0 голосов
/ 20 февраля 2012

После преобразования в XElement вы можете использовать метод XPathSelectElements extension вместе с «//» для выбора всех элементов с определенным именем.

using System.Xml.XPath;

...

var path = "<Your path>";
var doc = XElement.Load(path);

var subPages = doc.XPathSelectElements("//subpage[@pageId != '']")
                  .Select(x => new
                               {
                                   Id = Convert.ToInt32(x.Attribute("pageId").Value,
                                   SubTitle = x.Attribute("subtitle").Value,
                                   Enabled = Convert.ToBoolean(x.Attribute("enabled").Value)
                               }
                  )
                  .ToDictionary(u => u.Id, u => new Tuple<int, string, string>(u.Id, u.SubTitle, u.Enabled)
0 голосов
/ 20 февраля 2012

Как насчет этого?

        string path = @"..\LinqToXml\LinqToXml\config.Xml";

        XElement doc2 = XElement.Load(path);

         var element = from t in doc2.Elements("group").Elements("page").Descendants() select t;

        foreach (var el in element)
        {
            if (el.HasAttributes)
            {
                foreach (var att in el.Attributes())
                {
                    Debug.WriteLine(att.Value);
                }
            }
        }
0 голосов
/ 20 февраля 2012

Забудьте XMLDocument и используйте вместо этого LINQ to XML.После того, как вы загрузили документ, используя XDocument.Load(), вы можете использовать код, такой как

IEnumerable<XElement> de=
    from el in xmlTree.Descendants("subpage")
    select el;
    foreach (XElement el in de)
Console.WriteLine(el.Attributes("title"), el.Attributes("pageID"));//etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...