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();