我正在尝试在下面的示例中获取所有子页面。 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));
}
}
}
}
}
}
我做错了什么?我只想浏览子页面下面的所有子页面并获取可用的属性。
提前致谢。
答案 0 :(得分:2)
也许尝试使用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
。
编辑:
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 :(得分:1)
您的问题在这里:
XmlNodeList subpages = page.SelectNodes("subpage");
subpages
仅包含subpage
中包含的元素的子page
元素。
但是,您需要page
的所有后代。
<强>解决方案强>:
将此行替换为:
XmlNodeList subpages = page.SelectNodes(".//subpage");
变量subpages
现在包含当前节点subpage
的所有page
个后代。
答案 2 :(得分:0)
忘记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
答案 3 :(得分:0)
这个怎么样?
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);
}
}
}
答案 4 :(得分:0)
转换为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)