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

Posted

技术标签:

【中文标题】C#如何从xml文件中获取所有元素名称【英文标题】:C# how can I get all elements name from a xml file 【发布时间】:2010-10-25 06:44:56 【问题描述】:

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

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

我想获取元素的名称“BookName”。 "ISBN" 和 "PublishDate" 仅包含这些名称,不包括 "BookStoreInfo" 及其子节点的名称

试了好几种方法都不行,怎么办?

【问题讨论】:

【参考方案1】:

好吧,使用 XDocument 和 LINQ-to-XML:

foreach(var name in doc.Root.DescendantNodes().OfType<XElement>()
        .Select(x => x.Name).Distinct())

    Console.WriteLine(name);

不过,类似的路线还有很多。

【讨论】:

非常感谢。我不熟悉 LINQ-XML。但它工作得很好。还有一件事,我更新了上面的问题。我怎样才能只在 元素下获取子节点的名称。 如果您的意思是在“书”下(根据更新的问题) - 类似于:doc.Root.Element("Book").DescendantNodes()... 是的,我就是这个意思。代码正在运行,再次感谢您! @MarcGravell 我们可以使用这种方法获取整个节点集合吗,我的意思是具有特定名称的整个节点 @Chintan_Patel 在下面指出,您可以使用 GetElementsByTagName 方法在一行中完成【参考方案2】:

使用 XPath

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

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

【讨论】:

【参考方案3】:

我同意 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]);
        
    

【讨论】:

【参考方案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 使它更漂亮),但无论您的环境如何,这都应该可以完成工作。

【讨论】:

【参考方案5】:

如果您使用的是 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();

【讨论】:

没有 C# 3.5 这样的东西;不过,它使用 C# 3.0 和 .NET 3.5。 很好的答案。你如何计算每个标签出现的次数?【参考方案6】:

您可以尝试使用XPATH。

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

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

【讨论】:

【参考方案7】:

如果 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];

            
        

【讨论】:

【参考方案8】:

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

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

【讨论】:

以上是关于C#如何从xml文件中获取所有元素名称的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# ASP.Net 从 XML 文档中获取特定 XML 元素的列表?

如何从列表“StandardListItem”中的 JSON 文件中的元素“名称”中获取所有值?

XML解析器(Unmarshal)使用JaxB从xml文件中获取元素

如何使用 JDOM 编写和获取具有相同名称的同一级别的所有 xml 元素

如何在将 xml 反序列化为 c# 对象时获取单个 xml 元素的多个值?

如何在 c# 中读取由代码度量生成的这个 xml 文件