从 XML 文件中读取特定的 XML 元素

Posted

技术标签:

【中文标题】从 XML 文件中读取特定的 XML 元素【英文标题】:Reading specific XML elements from XML file 【发布时间】:2019-12-28 12:24:39 【问题描述】:

我有以下 XML 文件

<lexicon>
<word>
  <base>a</base>
  <category>determiner</category>
  <id>E0006419</id>
</word>
<word>
  <base>abandon</base>
  <category>verb</category>
  <id>E0006429</id>
  <ditransitive/>
  <transitive/>
</word>
<word>
  <base>abbey</base>
  <category>noun</category>
  <id>E0203496</id>
</word>
<word>
  <base>ability</base>
  <category>noun</category>
  <id>E0006490</id>
</word>
<word>
  <base>able</base>
  <category>adjective</category>
  <id>E0006510</id>
  <predicative/>
  <qualitative/>
</word>
<word>
  <base>abnormal</base>
  <category>adjective</category>
  <id>E0006517</id>
  <predicative/>
  <qualitative/>
</word>
<word>
  <base>abolish</base>
  <category>verb</category>
  <id>E0006524</id>
  <transitive/>
</word>
</lexicon>

我需要用 C# 应用程序读取这个文件,如果只有 categoryverb 我想打印它的整个元素 word。 我该怎么做?

【问题讨论】:

你试过使用 Linq to XML 吗? 你能告诉我怎么做吗? @Ruba 您应该先进行自己的研究,然后在遇到麻烦时来。谷歌搜索或搜索 SO 将向您展示如何解析 XML。 【参考方案1】:

你可以使用 linq to xml。

    var xmlStr = File.ReadAllText("fileName.xml");


    var str = XElement.Parse(xmlStr);

    var result = str.Elements("word").
Where(x => x.Element("category").Value.Equals("verb")).ToList();

    Console.WriteLine(result);

【讨论】:

注意:XElement 类位于 System.Xml.Linq 命名空间中【参考方案2】:

您也可以使用XPath。有点老式但仍然有效:

using System.Xml;

...

XmlDocument xmlDocument;

xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);

foreach (XmlElement xmlElement in 
    xmlDocument.DocumentElement.SelectNodes("word[category='verb']"))

    Console.Out.WriteLine(xmlElement.OuterXml);

【讨论】:

我不同意 XPath 是老式的,我非常喜欢 XPath 我的意思是......你可以随心所欲地喜欢它,但与 linq to xml 相比,它是老式的。 @BrootsWaymb 你能做到:xDoc.XPathSelectElement("/root/child/element")linq-to-xml 在一行吗?不使用Descendants,因为它看起来无处不在。【参考方案3】:

我就是这样做的(下面的代码已经过测试,下面提供了完整的源代码),首先创建一个具有公共属性的类

    class Word
    
        public string Base  get; set; 
        public string Category  get; set; 
        public string Id  get; set; 
    

使用带有 INPUT_DATA 的 XDocument 加载以进行演示,并使用 lexicon 查找元素名称。 . .

    XDocument doc = XDocument.Parse(INPUT_DATA);
    XElement lex = doc.Element("lexicon");

确保有一个值并使用 linq 从中提取单词元素。 . .

    Word[] catWords = null;
    if (lex != null)
    
        IEnumerable<XElement> words = lex.Elements("word");
        catWords = (from itm in words
                    where itm.Element("category") != null
                        && itm.Element("category").Value == "verb"
                        && itm.Element("id") != null
                        && itm.Element("base") != null
                    select new Word() 
                    
                        Base = itm.Element("base").Value,
                        Category = itm.Element("category").Value,
                        Id = itm.Element("id").Value,
                    ).ToArray<Word>();
    

where 语句检查类别元素是否存在并且类别值不为空,然后再次检查它是否是动词。然后检查其他节点是否也存在。 . .

linq 查询会返回一个 IEnumerable 对象,因此我们可以调用 ToArray() 将整个集合强制转换为我们想要的类型。

然后打印得到 . . .

[Found]
 Id: E0006429
 Base: abandon
 Category: verb

[Found]
 Id: E0006524
 Base: abolish
 Category: verb

完整来源

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace test

    class Program
    

        class Word
        
            public string Base  get; set; 
            public string Category  get; set; 
            public string Id  get; set; 
        

        static void Main(string[] args)
        
            XDocument doc = XDocument.Parse(INPUT_DATA);
            XElement lex = doc.Element("lexicon");
            Word[] catWords = null;
            if (lex != null)
            
                IEnumerable<XElement> words = lex.Elements("word");
                catWords = (from itm in words
                            where itm.Element("category") != null
                                && itm.Element("category").Value == "verb"
                                && itm.Element("id") != null
                                && itm.Element("base") != null
                            select new Word() 
                            
                                Base = itm.Element("base").Value,
                                Category = itm.Element("category").Value,
                                Id = itm.Element("id").Value,
                            ).ToArray<Word>();
            

            //print it
            if (catWords != null)
            
                Console.WriteLine("Words with <category> and value verb:\n");
                foreach (Word itm in catWords)
                    Console.WriteLine("[Found]\n Id: 0\n Base: 1\n Category: 2\n", 
                        itm.Id, itm.Base, itm.Category);
            
        

        const string INPUT_DATA =
        @"<?xml version=""1.0""?>
        <lexicon>
        <word>
          <base>a</base>
          <category>determiner</category>
          <id>E0006419</id>
        </word>
        <word>
          <base>abandon</base>
          <category>verb</category>
          <id>E0006429</id>
          <ditransitive/>
          <transitive/>
        </word>
        <word>
          <base>abbey</base>
          <category>noun</category>
          <id>E0203496</id>
        </word>
        <word>
          <base>ability</base>
          <category>noun</category>
          <id>E0006490</id>
        </word>
        <word>
          <base>able</base>
          <category>adjective</category>
          <id>E0006510</id>
          <predicative/>
          <qualitative/>
        </word>
        <word>
          <base>abnormal</base>
          <category>adjective</category>
          <id>E0006517</id>
          <predicative/>
          <qualitative/>
        </word>
        <word>
          <base>abolish</base>
          <category>verb</category>
          <id>E0006524</id>
          <transitive/>
        </word>
        </lexicon>";

    

【讨论】:

【参考方案4】:

或者,您可以通过XPathSelectElements 方法使用XPath 查询:

var document = XDocument.Parse(yourXmlAsString);
var words = document.XPathSelectElements("//word[./category[text() = 'verb']]");

【讨论】:

【参考方案5】:
XDocument xdoc = XDocument.Load(path_to_xml);
var word = xdoc.Elements("word")
               .SingleOrDefault(w => (string)w.Element("category") == "verb");

This query 将返回整个单词XElement。如果类别为verb 的单词元素不止一个,那么您将获得InvalidOperationException。如果没有类别为verb 的元素,则结果将为null

【讨论】:

以上是关于从 XML 文件中读取特定的 XML 元素的主要内容,如果未能解决你的问题,请参考以下文章

如何读取 XML 文件并删除一组标签

使用 Linq 从在线 XML 文件中读取数据

从文件加载 XML 并解析?

使用 XPathEvaluate 从 camt053 xml 文件中读取数据

c#中怎样读取xml文件中的数据,怎样动态将数据存储到xml文件中去?

读取XML文件中获取特定值