LINQ/XML - 遍历查询结果(返回低于预期的元素)

LINQ/XML - loop through results of a query (is returning an element lower than expected)

我正在尝试遍历 LINQ/XML 查询的结果。 当我使用 .Element(1).Value 时,我可以 return 一个字符串结果,但现在我想 return 所有 Elements() 并循环遍历它们。

我在循环中显示结果的值,它只显示元素 "Name" 及其值。我期望该值包括 "Character" 的所有 XML。

您可以 运行 并在此处查看结果: https://dotnetfiddle.net/g0nURp

我不知道我是否应该按照下面的方式做,或者 1) IEnumerable 结果 = 要么 2) 在 Select 语句中列出我想要的所有值(如果我那样做,我仍在寻找你如何循环结果)。

using System;
using System.Linq;
using System.Xml.Linq;
using System.Collections;

public class Program
{
    public static void Main()
    {
           XElement xelGOT =
              new XElement("GameOfThrones",
                 new XElement("Characters",
                     new XElement("Character",
                         new XAttribute("Status", "deceased"),
                         new XElement("Name", "Daenerys Targaryen"),
                         new XElement("Actor", "Emilia Clarke")
                         ),
                     new XElement("Character",
                         new XAttribute("Status", "living"),
                         new XElement("Name", "Jon Snow"),
                         new XElement("Actor", "Kit Harrington")
                         ),
                     new XElement("Character",
                         new XAttribute("Status", "living"),
                         new XElement("Name", "Tyrion Lannister"),
                         new XElement("Actor", "Peter Dinklage")
                         )
                      )
                );

            // This one works (except for the "orderby") 
            string secondLivingCharacter =
                (from xchar in xelGOT.Elements("Characters").First().Elements("Character")
                 where (string)xchar.Attribute("Status").Value == "living"
                 //orderby xchar.Element("Name")
                 select xchar).ElementAt(1).Value;
            Console.WriteLine("secondLivingCharacter=" + secondLivingCharacter); 

            // Get all the living characters 
            IEnumerable results =   
                (from xchar in xelGOT.Elements("Characters").First().Elements("Character")
                where (string) xchar.Attribute("Status").Value == "living"
                select xchar).Elements();

            foreach (var result in results.Cast<XElement>())
            {
                Console.WriteLine("\n\nDebug result=" + result.ToString()); 
                Console.WriteLine(
                          " Character=" + result.Element("Name").Value +
                          " Actor=" + result.Element("Actor").Value +
                          " Status=" + result.Attribute("Status")
                     );
            }

    }
}

想要的结果是循环打印两个匹配字符的name/actor。

实际输出结果和错误:

secondLivingCharacter=Tyrion LannisterPeter Dinklage


    Debug result=<Name>Jon Snow</Name>
    Run-time exception (line 48): Object reference not set to an instance of an object.

    Stack Trace:

    [System.NullReferenceException: Object reference not set to an instance of an object.]
       at Program.Main() :line 48

请尝试以下操作。

c#

void Main()
{
    XElement xelGOT =
              new XElement("GameOfThrones",
                 new XElement("Characters",
                     new XElement("Character",
                         new XAttribute("Status", "deceased"),
                         new XElement("Name", "Daenerys Targaryen"),
                         new XElement("Actor", "Emilia Clarke")
                         ),
                     new XElement("Character",
                         new XAttribute("Status", "living"),
                         new XElement("Name", "Jon Snow"),
                         new XElement("Actor", "Kit Harrington")
                         ),
                     new XElement("Character",
                         new XAttribute("Status", "living"),
                         new XElement("Name", "Tyrion Lannister"),
                         new XElement("Actor", "Peter Dinklage")
                         )
                      )
                );

    // This one works (except for the "orderby") 
    string secondLivingCharacter =
        (from xchar in xelGOT.Elements("Characters").First().Elements("Character")
         where xchar.Attribute("Status").Value.Equals("living")
         orderby xchar.Element("Name").value descending
         select xchar).ElementAt(1).Value;
    Console.WriteLine("secondLivingCharacter='{0}'{1}", secondLivingCharacter, Environment.NewLine);

    // Get all the living characters 
    var results =
        (from xchar in xelGOT.Descendants("Character")
         where (string)xchar.Attribute("Status").Value == "living"
         select xchar);

    foreach (var result in results)
    {
        Console.WriteLine("Character='{0}' Actor='{1}' Status='{2}'"
             , result.Element("Name").Value
             , result.Element("Actor").Value
             , result.Attribute("Status").Value);
    }

}