C# XML 读取:读取具有相同节点名称的节点

  • 本文关键字:节点 读取 XML c# arrays xml
  • 更新时间 :
  • 英文 :


我有下面的XML,其中包含更多的"字符串"节点(字符串节点的数量由工具定义 - 向其中添加了多少语言(我使用 system.xml 将每个节点保存到一个字符串中,如下面的代码所示:

是否有选项可以将每个"字符串"的InnerText保存到数组中?我也尝试了下面的代码(for loop(,但不知道如何定义循环的数量(字符串数字(。任何建议将不胜感激。

valid = TBElement.GetElementsByTagName("Valid")[0].InnerText;
for (int b = 0; b == stringnumber; b++)
{
    languages[b] = TBElement.GetElementsByTagName("Languages/string")[0].InnerText;
}

下面是 XML:

<ArrayOfGlobalInfo>
 <GlobalInfo>
  <NumberOfEntries>2</NumberOfEntries>
  <LanguageNewDefaultOptions />
  <Languages>
    <string>eng</string>
    <string>ger</string>
    <string>ita</string>
    <string>fre</string>
  </Languages>
  <Valid>true</Valid>
 </GlobalInfo>
</ArrayOfGlobalInfo>

在一个指令中使用 XML Linq 执行此操作

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

namespace ConsoleApplication49
{
    class Program
    {
        const string FILENAME = @"c:temptest.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            string[] languages = doc.Descendants("string").Select(x => (string)x).ToArray();
        }
    }
}

循环数可以从下面找到

TBElement.GetElementsByTagName("Languages/string").Count()

只需将其存储在变量中并在循环条件中使用它即可

 var stringnumber = TBElement.GetElementsByTagName("Languages/string").Count()

试试这个:

var stringElements = TBElement.GetElementsByTagName("Languages/string");
List<string> languages = new List<string>();
foreach (var element in stringElements)
    languages.Add(element.InnerText);

如果您更喜欢数组:

var stringElements = TBElement.GetElementsByTagName("Languages/string");
string[] languages = new string[stringElements.Count];
for (int i = 0; i != stringElements.Count; ++i)
    languages[i] = stringElements[i].InnerText;

您可以按照以下方式操作:

XDocument xdoc = XDocument.Load("YourXMLFile");
XmlNodeList elemList = xdoc.GetElementsByTagName("string");
        for (int i = 0; i < elemList.Count; i++)
        {
            Console.WriteLine(elemList[i].InnerText);
        }

另一种解决方案是这样的:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("Your file path");
XmlNodeList dataNodes = xmlDoc.SelectNodes("/ArrayOfGlobalInfo/GlobalInfo/Languages/string");
foreach (XmlNode node in dataNodes)
                {
//Your code goes here
}

您的问题的直接答案是这样做:

xmlNodeList.Cast<XmlNode>().Select(n => n.InnerText).ToArray();

。其中 xmlNodeList 是 GetElementsByTagName(( 中成功计算的 XPath 表达式的结果。

但您可以考虑:

  • 使用XDocument而不是XmlDocument是否更好
  • 是否真的需要一个数组,因为 XmlNodeList 已经有一个 .计数属性

这说明了您的一些选项:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace _43387906
{
    class Program
    {
        private static string _xml = "<ArrayOfGlobalInfo>rn <GlobalInfo>rn  <NumberOfEntries>2</NumberOfEntries>rn  <LanguageNewDefaultOptions />rn  <Languages>rn    <string>eng</string>rn    <string>ger</string>rn    <string>ita</string>rn    <string>fre</string>rn  </Languages>rn  <Valid>true</Valid>rn </GlobalInfo>rn</ArrayOfGlobalInfo>";
        static void Main(string[] args)
        {
            try
            {
                var xDocument = XDocument.Parse(_xml);
                UseXDocumentVerbose(xDocument);
                UseXDocumentShorter(xDocument);
                var xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(_xml);
                UseXmlDocument(xmlDocument);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadLine();
        }
        private static void UseXmlDocument(XmlDocument xmlDocument)
        {
            var languages = xmlDocument.SelectNodes("ArrayOfGlobalInfo/GlobalInfo/Languages/string");
            //You can use languages.Count without converting to an array
            for (int i = 0; i < languages.Count; i++)
            {
                Console.WriteLine(languages[i].InnerText);
            }
            //The trick is to use Cast<T>() and ToArray()
            var languagesArray = languages.Cast<XmlNode>().Select(n => n.InnerText).ToArray();
            for (int i = 0; i < languagesArray.Length; i++)
            {
                Console.WriteLine(languagesArray[i]);
            }
        }
        private static void UseXDocumentShorter(XDocument xDocument)
        {
            if (xDocument.Root.Name != "ArrayOfGlobalInfo")
                throw new Exception("Root isn't ArrayOfGlobalInfo");
            var languages = xDocument.Root
                                     .Elements("GlobalInfo")
                                     .SelectMany(i => i.Elements("Languages"))
                                     .SelectMany(l => l.Elements("string"))
                                     .Select(s => s.Value).Where(s => !string.IsNullOrWhiteSpace(s))
                                     .ToArray();
            for (int i = 0; i < languages.Length; i++)
            {
                Console.WriteLine(languages[i]);
            }
        }
        private static void UseXDocumentVerbose(XDocument xDocument)
        {
            if (xDocument.Root.Name != "ArrayOfGlobalInfo")
                throw new Exception("Root isn't ArrayOfGlobalInfo");
            var globalInfoElements = xDocument.Root.Elements("GlobalInfo");
            var languageElements = globalInfoElements.SelectMany(i => i.Elements("Languages"));
            var languages = languageElements.SelectMany(l => l.Elements("string")).Select(s => s.Value).Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
            for (int i = 0; i < languages.Length; i++)
            {
                Console.WriteLine(languages[i]);
            }
        }
    }
}

最新更新