C# Попытка получить XML внутренний текст для вложенного узла - PullRequest
1 голос
/ 19 февраля 2020

Я могу успешно загрузить документ XMl и пересечь узлы. Как только я получу нужный мне узел, я начинаю устанавливать значения. Как мне работать с вложенными узлами?

Вот это xml:

<incident>
<id>1234</id>
<number>5678</number>
<name>This is a name</name>
<state>Awaiting Input</state>
<priority>Medium</priority>
<category>
    <id>99999</id>
    <name>Applications</name>
    <default_tags>applications</default_tags>
    <parent_id nil="true" />
    <default_assignee_id nil="true" />
</category>

Вот некоторые C#:

   id = node.SelectSingleNode("id").InnerText;  //works fine
   number = node.SelectSingleNode("number").InnerText;  //works fine

   name = node.SelectSingleNode("name").InnerText;  //works fine
   descHTML = node.SelectSingleNode("description").InnerText;  //works fine
   desc = node.SelectSingleNode("description_no_html").InnerText;  //works fine
   state = node.SelectSingleNode("state").InnerText;  //works fine
   priority = node.SelectSingleNode("priority").InnerText;  //works fine

   catagoryID = node.SelectSingleNode("category/id").InnerText; // null reference error
   catagoryName = node.SelectSingleNode("category/name").InnerText; // null reference error
   catagoryTags = node.SelectSingleNode("category/default_tags").InnerText; // null reference error

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Полагаю, вы используете класс XmlDocument, а CATEGORY NODE - единственный элемент, который будет иметь дочерние узлы, поэтому у меня есть этот метод для go через каждый элемент, включая подузлы (надеюсь, это кому-нибудь поможет).

string xml = 
@"<incident>
    <id>1234</id>
    <number>5678</number>
    <name>This is a name</name>
    <state>Awaiting Input</state>
    <priority>Medium</priority>
    <category>
        <id>99999</id>
        <name>Applications</name>
        <default_tags>applications</default_tags>
        <parent_id nil=""true"" />
        <default_assignee_id nil=""true"" />
    </category>
</incident>";

List<String> innerTextNode = new List<string>();
XmlDocument XmlDoc= new XmlDocument();
XmlDoc.LoadXml(xml);

XmlElement root = XmlDoc.DocumentElement;
XmlNodeList nodes = root.ChildNodes;
XmlNodeList childs;

foreach (XmlNode anode in nodes)
{
    // The next is for any NODE that will have childnodes
    // bool havechilds = anode.ChildNodes.OfType<XmlNode>().Any(x => x.NodeType != XmlNodeType.Text)

    if (!anode.LocalName.Equals("category", StringComparison.CurrentCulture))
    {
        // The node is only text, no has childnodes
        // So capturing InnerText
        innerTextNode.Add(anode.InnerText);
    }
    else
    {
        childs = nodo.ChildNodes;
        foreach (XmlNode childone in childs)
        {
            // So capturing InnerText
            innerTextNode.Add(childone.InnerText);
        }
    }
}
0 голосов
/ 19 февраля 2020

Если вы читаете различные элементы, которые могут существовать или не существовать, используйте ?. после метода SelectSingleNode. Это гарантирует, что вы не получите ошибку Object Reference Not Set to an Instance of an object.

?., в сущности, проверяет, есть ли значение, прежде чем приступить к оценке следующего метода или свойства.

string xml = @"<incident>
<id>1234</id>
<number>5678</number>
<name>This is a name</name>
<state>Awaiting Input</state>
<priority>Medium</priority>
<category>
    <id>99999</id>
    <name>Applications</name>
    <default_tags>applications</default_tags>
    <parent_id nil=""true"" />
    <default_assignee_id nil=""true"" />
</category>
</incident>";

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xml);
        var node = doc.DocumentElement;

        var id = node.SelectSingleNode("id")?.InnerText;  //works fine
       var number = node.SelectSingleNode("number")?.InnerText;  //works fine

       var name = node.SelectSingleNode("name")?.InnerText;  //works fine
       var descHTML = node.SelectSingleNode("description")?.InnerText;  //ERRORS because there is no description.
       var desc = node.SelectSingleNode("description_no_html")?.InnerText;  //works fine
       var state = node.SelectSingleNode("state")?.InnerText;  //works fine
       var priority = node.SelectSingleNode("priority")?.InnerText;  //works fine

       var catagoryID = node.SelectSingleNode("//category/id")?.InnerText; // null reference error
       var catagoryName = node.SelectSingleNode("//category/name")?.InnerText; // null reference error
       var catagoryTags = node.SelectSingleNode("//category/default_tags")?.InnerText; // null reference error

        Console.WriteLine($"name: {name}");
        Console.WriteLine($"descHTML: {descHTML}");
        Console.WriteLine($"desc: {desc}");
        Console.WriteLine($"state: {state}");
        Console.WriteLine($"priority: {priority}");
        Console.WriteLine($"catagoryID: {catagoryID}");
        Console.WriteLine($"catagoryName: {catagoryName}");
        Console.WriteLine($"catagoryTags: {catagoryTags}");

Вывод на печать

name: This is a name
descHTML: 
desc: 
state: Awaiting Input
priority: Medium
catagoryID: 99999
catagoryName: Applications
catagoryTags: applications

Код на # dotnetfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...