如何在C#中获取XML的所有子节点

5

我有一个像这样的XML文档:

<Columns>
  <Column>
    <Name>A</Name>
    <Width>100</Width>
  </Column>
</Columns>

<Columns>

</Columns>

<Columns>
  <Column>
    <Name>C</Name>
    <Width>300</Width>
  </Column>
  <Column>
    <Name>C1</Name>
    <Width>310</Width>
  </Column>
</Columns>

我正在获取他们的名称和宽度文本,并将它们存储在一个列表中。
var man = new XmlNamespaceManager(xdoc.NameTable);
man.AddNamespace("ns", "http://schemas.microsoft.com/project");
List <string> lstText = new List<string>();
List <List<string>> lst = new List<List<string>>();
XmlNodeList xnList = xdoc.SelectNodes("/ns:Columns/ns:Column", man);

foreach (XmlNode xn in xnList)
        {
           lstText.Add(xn["Name"].InnerText));
           lstText.Add(xn["Width"].InnerText));
        }
lst.Add(lstText);

所以,我只能得到这些值:A和100、C和300。我也想得到C1和310。怎样才能得到它们呢?

编辑:某些列没有列名,某些列有一个或多个列名。在此示例中,我的列表有3个元素:

lst[0][0] = {A, 100}
lst[1][0] = null
lst[2][0] = {C, 300}, lst[2][1] = {C1, 310}

你想把所有的元素加载到一个像字典一样的集合中吗? - Kosala W
抱歉,我更新了问题。你有什么想法吗? - 1teamsah
好的。我会尽快发布代码。 - Kosala W
4个回答

3
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;

public class MainClass
{
    public static void Main()
    {
        XmlDocument mDocument = new XmlDocument();
        XmlNode mCurrentNode;

        mDocument.Load("XPathQuery.xml");
        mCurrentNode = mDocument.DocumentElement;


        XmlNodeList nodeList = mCurrentNode.SelectNodes("*");
        DisplayList(nodeList);
    }

    static void DisplayList(XmlNodeList nodeList)
    {
        foreach (XmlNode node in nodeList)
        {
            RecurseXmlDocumentNoSiblings(node);
        }
    }

    static void RecurseXmlDocumentNoSiblings(XmlNode root)
    {
        if (root is XmlElement)
        {
            Console.WriteLine(root.Name);
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild);
        }
        else if (root is XmlText)
        {
            string text = ((XmlText)root).Value;
            Console.WriteLine(text);
        }
        else if (root is XmlComment)
        {
            string text = root.Value;
            Console.WriteLine(text);
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild);
        }
    }

    static void RecurseXmlDocument(XmlNode root)
    {
        if (root is XmlElement)
        {
            Console.WriteLine(root.Name);
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild);
            if (root.NextSibling != null)
                RecurseXmlDocument(root.NextSibling);
        }
        else if (root is XmlText)
        {
            string text = ((XmlText)root).Value;
            Console.WriteLine(text);
        }
        else if (root is XmlComment)
        {
            string text = root.Value;
            Console.WriteLine(text);
            if (root.HasChildNodes)
                RecurseXmlDocument(root.FirstChild);
            if (vroot.NextSibling != null)
                RecurseXmlDocument(root.NextSibling);
        }
    }
}

如果我们只想针对“Column”节点进行此操作,我们应该怎么做? - 1teamsah
请参考以下链接:http://www.java2s.com/Tutorial/CSharp/0540__XML/SelectAllChildNodes.htm 和 http://www.java2s.com/Tutorial/CSharp/0540__XML/SelectBySpecificAuthorNode.htm。 - Karthikeyan

1
    public readonly Dictionary<string, int> XmlValues = new Dictionary<string, int>();
    public void Analyze(XmlDocument xml)
    {
        RecurseXmlDocument(xml.LastChild);
    }

    void RecurseXmlDocument(XmlNode root)
    {
        switch (root.NodeType)
        {
            case XmlNodeType.Element:
                if (root.HasChildNodes)
                    RecurseXmlDocument(root.FirstChild);
                if (root.NextSibling != null)
                    RecurseXmlDocument(root.NextSibling);
                break;

            case XmlNodeType.Text:
                DictionayHelper.AddValue(XmlValues, root.Value);
                break;
        }
    }

0
使用 System.Xml.Linq:
const string name = "Name";
var xml = XDocument.Load(@"P:\athToYour\columns.xml");
var columns = xml.Descendants(name).Select(x => new
{
    Name = x.Value,
    Width = x.ElementsAfterSelf("Width").FirstOrDefault().Value
})
.ToDictionary(x=> x.Name, x=> x.Width);
columns.Dump();

0
你可以这样做;如果需要,你可以将其缩减为2行。
                var xDoc = XDocument.Load(@"c:\XPathQuery.xml");
        //this query gets Names and widths
        var widths = xDoc.Descendants().Where(x => x.Name.LocalName.Equals("Name")).Select(x => new { Name = x.Value, Width = x.ElementsAfterSelf().First().Value }).ToList();

        //if you want to loop through the collection, you can do like this.
        foreach (var width in widths)
        {
            var name = width.Name;
            var value = width.Width;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接