C#如何从xml文件中获取所有元素名称

时间:2009-05-11 12:55:24

标签: c# xml

我想从xml文件中获取所有元素名称,例如xml文件是,

<BookStore>
  <BookStoreInfo>
    <Address />
    <Tel />
    <Fax />
  <BookStoreInfo>
  <Book>
    <BookName />
    <ISBN />
    <PublishDate />
  </Book>
  <Book>
   ....
  </Book>
</BookStore>

我想获得元素的名称“BookName”。 “ISBN”和“PublishDate”只有那些名称,不包括“BookStoreInfo”及其子节点的名称

我尝试了几种方法,但是不起作用,我怎么能这样做?

8 个答案:

答案 0 :(得分:30)

好吧,XDocument和LINQ-to-XML:

foreach(var name in doc.Root.DescendantNodes().OfType<XElement>()
        .Select(x => x.Name).Distinct())
{
    Console.WriteLine(name);
}

但是有很多类似的路线。

答案 1 :(得分:8)

使用XPath

XmlDocument xdoc = new XmlDocument(); 
xdoc.Load(something);
XmlNodeList list = xdoc.SelectNodes("//BookStore");

为您提供一个列表,其中包含名为BookStore的文档中的所有节点

答案 2 :(得分:5)

我同意Adam,理想的条件是拥有一个定义xml文档内容的模式。但是,有时这是不可能的。这是一个简单的方法,用于迭代xml文档的所有节点,并使用字典来存储唯一的本地名称。我喜欢跟踪每个本地名称的深度,所以我使用int列表来存储深度。请注意,XmlReader“很容易在内存中”,因为它不像XmlDocument那样加载整个文档。在某些情况下,它没有什么区别,因为xml数据的大小很小。在以下示例中,使用XmlReader读取18.5MB文件。使用XmlDocument加载这些数据的效果不如使用XmlReader读取和采样其内容。

string documentPath = @"C:\Docs\cim_schema_2.18.1-Final-XMLAll\all_classes.xml";

Dictionary<string, List<int>> nodeTable = new Dictionary<string, List<int>>();
using (XmlReader reader = XmlReader.Create(documentPath))
{
    while (!reader.EOF)
    {
        if (reader.NodeType == XmlNodeType.Element)
        {
            if (!nodeTable.ContainsKey(reader.LocalName))
            {
                nodeTable.Add(reader.LocalName, new List<int>(new int[] { reader.Depth }));
            }
            else if (!nodeTable[reader.LocalName].Contains(reader.Depth))
            {
                nodeTable[reader.LocalName].Add(reader.Depth);
            }
        }
        reader.Read();
    }
}
Console.WriteLine("The node table has {0} items.",nodeTable.Count);
foreach (KeyValuePair<string, List<int>> kv in nodeTable)
{
    Console.WriteLine("{0} [{1}]",kv.Key, kv.Value.Count);
    for (int i = 0; i < kv.Value.Count; i++)
    {
        if (i < kv.Value.Count-1)
        {
            Console.Write("{0}, ", kv.Value[i]);
        }
        else
        {
            Console.WriteLine(kv.Value[i]);
        }
    }
}

答案 3 :(得分:4)

纯粹主义者这样做的方式(并且,公平地,正确的方式)将是具有模式契约定义并以这种方式阅读它。话虽这么说,你可以做这样的事......

List<string> nodeNames = new List<string>();

foreach(System.Xml.XmlNode node in doc.SelectNodes("BookStore/Book"))
{
    foreach(System.Xml.XmlNode child in node.Children) 
    {
        if(!nodeNames.Contains(child.Name)) nodeNames.Add(child.Name);
    }
}

不可否认,这是获取Book节点子节点的不同节点名称列表的基本方法,但是您没有在环境中指定其他许多节点名称(如果您有3.5,那么您例如,可以使用LINQ to XML使这更漂亮一点,但无论您的环境如何,这都应该完成工作。

答案 4 :(得分:3)

如果您使用的是C#3.0,则可以执行以下操作:

var data = XElement.Load("c:/test.xml"); // change this to reflect location of your xml file

var allElementNames = 
    (from e in in data.Descendants()
    select e.Name).Distinct();

答案 5 :(得分:2)

您可以尝试使用XPATH

XmlDocument doc = new XmlDocument();
doc.LoadXml("xml string");

XmlNodeList list = doc.SelectNodes("//BookStore/Book");

答案 6 :(得分:2)

如果 BookStore 是你的根元素,那么你可以尝试使用代码

XmlDocument doc = new XmlDocument();
        doc.Load(configPath);
        XmlNodeList list = doc.DocumentElement.GetElementsByTagName("Book");
        if (list.Count != 0)
        {
            for (int i = 0; i < list[0].ChildNodes.Count; i++)
            {
                XmlNode child = list[0].ChildNodes[i];

            }
        }

答案 7 :(得分:-1)

我在这里找到的在线工具可以很好地提取这些元素的名称 - 只需上传XML文件,然后将这些名称打印为结果网页。

http://taporware.ualberta.ca/~taporware/xmlTools/listxml.shtml

enter image description here