C# разбить внутренний текст XML или разобрать innerxml

У меня есть XML-файл со структурой, похожей на эту

<entry name="something">
  <members>
    <member>aaa</member>
    <member>bbb</member>
  </members>
</entry>
<entry name="something_else">
  <members>
    <member>ccc</member>
    <member>ddd</member>
  </members>
</entry>

Мне нужно иметь возможность получать значения из каждого из узлов-членов для хранения данных. если я использую свойство innertext, он объединяет значения (aaabbb). нет ничего заметного, чтобы разделить строку на. Я также могу использовать внутренний XML, но тогда я просто получаю строку со структурой XML (aaa bbb<\ member>)

Каков наилучший способ извлечь каждое значение из элементов XML и сохранить его в строковом массиве?

вот что я пытался

foreach (XmlNode grpNode in GrpList)
{
    subNode = grpNode.Attributes["name"];
    if (subNode != null)
    {
        Obj = grpNode.Attributes["name"].Value;
    }

    subNode = grpNode["members"];
    if (subNode != null)
    {
        string innerXml = string.Empty;
        innerXml = grpNode["members"].InnerXml.ToString();

        string[] tempArrary = innerXml.Split(new char[] {'>', '<'});
    }
}

5 ответов

Решение

Вам нужно перебрать дочерние элементы внутри membersтак что-то вроде:

foreach (var node in grpNode["members"].ChildNodes)
{
    var value = node.InnerText;
}

Тем не менее, вам будет лучше использовать LINQ to XML, если у вас нет особых причин использовать XmlDocument, Это дает вам гораздо более выразительный код, например:

var doc = XDocument.Parse(xml);

var something = doc.Descendants("entry")
    .Where(e => (string)e.Attribute("name") == "something")
    .Single();

var somethingMembers = something.Descendants("member")
    .Select(e => e.Value)
    .ToArray();

Вы можете использовать Xpath для перебора узлов Entry и получения членов внутри него следующим образом

string xml = "<root><entry name='something'>" +
              "<members>" + 
                "<member>aaa</member>" + 
                "<member>bbb</member>" + 
              "</members>" + 
            "</entry>" + 
            "<entry name='something_else'>" + 
              "<members>" + 
                "<member>ccc</member>" + 
                "<member>ddd</member>" + 
             "</members>" +
            "</entry></root>";

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

            var memsList = doc.SelectNodes("//entry");
            foreach (XmlNode a in memsList)
            {
                Console.WriteLine(a.Attributes["name"].Value);

                var memList = a.SelectNodes("members/member");

                foreach(XmlNode x in memList)
                    Console.WriteLine(x.InnerText);
            }

Предоставленный вами xml недействителен. Но при условии, что вы просто хотите внутренний текст всех member узлы в массив строк, я бы просто использовал Linq-To-Xml (XDocument):

var results = XDocument.Parse(xmlString)
                       .Descendants("member")
                       .Select(m => m.Value)
                       .ToArray();

Это должно сделать трюк:

XDocument xdoc = XDocument.Load(@"Path/to/file");
var result = xdoc.Descendants("member").Select (x => x.Value).ToArray();

Результат:

Демонстрационный код

Даже если вы используете старый XmlDocument API, добавив .OfType<XmlNode>() Вы можете конвертировать XmlNodeList для общего перечислимого и тем самым смешать в некотором синтаксисе linq и лямбда, например:

var tempArrary = subNode.SelectNodes("member").OfType<XmlNode>().Select(n => n.InnerText).ToArray();
Другие вопросы по тегам