【问题标题】:LINQ/XML - loop through results of a query (is returning an element lower than expected)LINQ/XML - 遍历查询结果(返回的元素低于预期)
【发布时间】:2020-06-15 16:59:19
【问题描述】:

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

我在循环中显示结果的值,它只显示元素“名称”及其值。我期望该值包括“字符”的所有 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")
                     );
            }

    }
}

所需的结果是循环并打印两个匹配字符的名称/演员。

实际输出结果和错误:

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#-4.0 linq-to-xml


    【解决方案1】:

    请尝试以下方法。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多