在C#中遍历XML样式站点地图文件

时间:2015-04-10 21:38:31

标签: c# xml sitemap

我要做的就是获取我的MySite.sitemap文件,从中取出所有节点,然后将其打印到文件中。长期目标是获取每个节点,看它是父母还是孩子。

MySite.sitemap

<?xml version="1.0" encoding="utf-8"?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
    <siteMapNode title="Grand Parent 1" roles="Grand Parent Role" description="A simple description that I might want to write to the text file.">
        <siteMapNode title="Parent" description="" roles="Parent Role">
            <siteMapNode title="Child 1" url="linkToPage.aspx" description="A short description." />
            <siteMapNode title="Child 2" url="linkToPage2.aspx" description="Another short description." />
        </siteMapNode>
        <siteMapNode title="Parent 2" description="" roles="Parent Role" />
            <siteMapNode title="Child 3" url="linkToPage3.aspx" description"A short description." />
            <siteMapNode title="Child 4" url="linkToPage4.aspx" description="Another short description." />
        </siteMapNode>
    </siteMapNode>
</siteMap>

C#

StreamWriter file = new StreamWriter("debugFile.txt");

file.WriteLine("Sitemap File: " + pathToSiteMapFile + siteMapFile);
XmlDocument xml = new XmlDocument();
xml.Load(pathToSiteMapFile + siteMapFile);
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
//manager.AddNamespace("s", xml.DocumentElement.NamespaceURI);
XmlNodeList nodeList = xml.SelectNodes("/siteMap/siteMapNode", manager);

foreach (XmlNode node in nodeList) {
    file.WriteLine("Trying to loop through xnlist...\r\n");
    file.WriteLine("Node: " + node.InnerText + "\r\n");
}

foreach (string str in testPages) {
    file.Write("File: " + str + "\r\n");
}
file.WriteLine("The foreach loop should have wrote all the nodes in here.\r\n");
file.Close();

如果有人可以帮我解决下一个问题,那么一旦我枚举了每个节点,我能够输入每个节点并根据每个节点内的内容做逻辑吗? IE节点a具有角色,而节点b则没有角色。

1 个答案:

答案 0 :(得分:1)

要使用SelectNodes,您需要明确指定命名空间(而不是XML文件中的命名空间前缀)和名称:

        XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable);
        ns.AddNamespace("myPrefix", @"http://schemas.microsoft.com/AspNet/SiteMap-File-1.0");

        var topNodes = xml.SelectNodes("/myPrefix:siteMap/myPrefix:siteMapNode", ns);
        var allNodes = xml.SelectNodes("//myPrefix:siteMapNode", ns);

此处查询字符串中的文本"myPrefix"是对通过调用ns.AddNamespace("myPrefix", ...)添加的命名空间的查找。它只是查找您自己创建的本地表。

要将所有节点输出到文件,您可以执行以下操作:

        foreach (XmlNode node in allNodes)
        {
            var text = new string(' ', node.AncestorsAndSelf().Count() - 1) + "Node: " + string.Join(", ", node.Attributes.Cast<XmlAttribute>().Select(a => a.Name + ": " + a.Value).ToArray());
            file.WriteLine(text);
        }

鉴于extension method

public static class XmlNodeExtensions
{
    public static IEnumerable<XmlNode> AncestorsAndSelf(this XmlNode node)
    {
        for (; node != null; node = node.ParentNode)
            yield return node;
    }
}

产生的输出如下:

 Node: title: Grand Parent 1, roles: Grand Parent Role, description: A simple description that I might want to write to the text file.
   Node: title: Parent, description: , roles: Parent Role
    Node: title: Child 1, url: linkToPage.aspx, description: A short description.
    Node: title: Child 2, url: linkToPage2.aspx, description: Another short description.
   Node: title: Parent 2, description: , roles: Parent Role
    Node: title: Child 3, url: linkToPage3.aspx, description: A short description.
    Node: title: Child 4, url: linkToPage4.aspx, description: Another short description.

顺便说一下,使用Linq-to-XML初始查询看起来要简单得多:

        var xDoc = XDocument.Load(pathToSiteMapFile + siteMapFile);

        var topElements = xDoc.Root.Elements(xDoc.Root.Name.Namespace + "siteMapNode");
        var allElements = xDoc.Root.Descendants(xDoc.Root.Name.Namespace + "siteMapNode");