【问题标题】:How to check if text node of xml file has a child node inside and get all data from them?如何检查xml文件的文本节点内部是否有子节点并从中获取所有数据?
【发布时间】:2015-02-11 07:02:56
【问题描述】:

我有 xml 文件。这只是该文件的一部分

1    <mainTerm>
2      <title> Abandonment </title>
3      <see> Maltreatment </see>
4    </mainTerm>
5    <mainTerm>
6      <title> Abasia <nemod>(-astasia) (hysterical) </nemod></title>
7      <code>F44.4</code>
8    </mainTerm>

我有很多&lt;mainTerm&gt;,我会遍历所有这些。我复制了元素的所有数据,但是当我到达第 6 行时,我遇到了问题。如何复制所有这些内容?我需要得到最后的字符串,它看起来像“Abasia (-astasia) (歇斯底里)”。

这是我的应用程序中与该文件一起使用的部分

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

            //Create XmlReaderSettings object
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            settings.IgnoreComments = true;

            //Create XmlReader object
            XmlReader xmlIn = XmlReader.Create(path, settings);

            Excel.Application xlApp;
            Excel.Workbook xlWorkBook;
            Excel.Worksheet xlWorkSheet;
            object misValue = System.Reflection.Missing.Value;

            xlApp = new Excel.Application();
            xlWorkBook = xlApp.Workbooks.Add(misValue);
if (xmlIn.ReadToDescendant("mainTerm"))
{
 do
 {
   xmlIn.ReadStartElement("mainTerm");                                                  

   nodes.Add(xmlIn.ReadElementContentAsString());                          

   nodes.Add(xmlIn.ReadElementContentAsString());                          

 } while (xmlIn.ReadToNextSibling("mainTerm"));
}

【问题讨论】:

  • 小心使用“文本节点”。文本节点是一种特定类型的 XML 节点,只能包含字符数据。我认为您的意思是 mainTerm 具有“混合内容”,即字符数据和元素。
  • 用你的代码更新问题
  • 是的,我的意思是“混合内容”,但我如何从混合内容中获取所有数据以获得结果“Abasia (-astasia) (歇斯底里)”。

标签: c# xml text xmlreader


【解决方案1】:

您可以使用 LINQ2XML。只需将您的 xml 结构包装在根节点中并获取所有标题元素,如下所示:

var xmlSrc = @"<?xml version=""1.0"" encoding=""UTF-8""?><xml><mainTerm>
  <title> Abandonment </title>
  <see> Maltreatment </see>
</mainTerm>
<mainTerm>
  <title> Abasia <nemod>(-astasia) (hysterical) </nemod></title>
  <code>F44.4</code>
</mainTerm></xml>";

var xml = XDocument.Parse(xmlSrc);
var mainTerms = xml.Root.Elements("mainTerm").ToList();
var titles = mainTerms.Elements("title").ToList();
foreach (var title in titles)
{
    System.Console.WriteLine(title.Value);
}

输出是:

Abandonment 
Abasia (-astasia) (hysterical) 

恕我直言,这比 XPath 和 XmlReader 容易得多。


使用Descendants 函数,您的ma​​inTerm 元素不必是根元素:

var mainTerms = xml.Root.Descendants("mainTerm").ToList();

这一行从 XML 文档中传递任何级别的所有 ma​​inTerm

【讨论】:

  • 是的,也许这很简单,但我有包含数千个节点的 xml 文件,而 甚至不是根元素。我的 xmlReader 工作正常,除了我的示例中的元素......我需要它修复的所有内容
  • 我已经用一个代码示例扩展了我的答案,该示例检索所有 mainTerm,而不管 XML 中的元素位置如何。
  • 好的。谢谢你。我会试试这个。
【解决方案2】:
【解决方案3】:

您需要使用 XmlDocument。我发现使用它比 xmlreader 容易得多。 用你的例子...

1    <mainTerm>
2      <title> Abandonment </title>
3      <see> Maltreatment </see>
4    </mainTerm>
5    <mainTerm>
6      <title> Abasia <nemod>(-astasia) (hysterical) </nemod></title>
7      <code>F44.4</code>
8    </mainTerm>

做这样的事情(对不起,没有时间通过​​编译器运行它......但这是一般的想法)

XmlDocument example = new XmlDocument();

example.Load(StringWhereYouHaveYourXML); //You can also load Xml in other ways... check documentation

XmlNodeList mainTerm = example.SelectNodes("/mainTerm/"); //Now you have your list of Mainterms...
//Check for children in your nodes now...
forEach(XmlNode a in mainTerm){
   //check in the Title node for children that is
   XmlNode title = a.SelectSingleNode("/Title/");
   if (title.HasChildNodes){
      XmlNode abasia = title.SelectSingleNode("/nemod/");
   }
}

从那里你可以对节点做你想做的事。但您现在已经更具体地定义了它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多