【问题标题】:LINQ to XML query attributesLINQ to XML 查询属性
【发布时间】:2013-07-22 06:19:11
【问题描述】:

使用 LINQ to XML,这是我的 XML 示例

<shows>
 <Show Code="456" Name="My Event Name">
   <Event Code="2453" VenueCode="39" Date="2010-04-13 10:30:00" /> 
   <Event Code="2454" VenueCode="39" Date="2010-04-13 13:30:00" /> 
   <Event Code="2455" VenueCode="39" Date="2010-04-14 10:30:00"  /> 
   <Event Code="2456" VenueCode="39" Date="2010-04-14 13:30:00" /> 
   <Event Code="2457" VenueCode="39" Date="2010-04-15 10:30:00" /> 
 </Show>

 <Show... />
 <Show... />
</shows>

如何返回特定节目的日期列表?我在查询字符串中传递了显示代码(“456”),并希望将所有日期/时间作为列表返回。

这是我目前的代码:

XDocument xDoc = XDocument.Load("path to xml");

            var feeds = from feed in xDoc.Descendants("Show")
                        where feed.Attribute("Code").Equals("456")
                        select new
                        {
                            EventDate = feed.Attribute("Date").Value
                        };

            foreach(var feed in feeds)
            {
                Response.Write(feed.EventDate + "<br />");
            }

但我没有返回任何结果

【问题讨论】:

  • @reinierpost:不,他正在尝试从 Show="456" 迭代子事件标签。值“2456”是一个事件代码。 ;-)
  • @Prutswonder - 你是对的!
  • @kb:如我的回答中所述,您试图在 Show 中而不是在 Event 中查找 Date 属性。您可能需要另一个“from”子句...
  • 我以为“Show”不会是它自己的.Descendant,但我知道什么......我只是路过。

标签: xml linq


【解决方案1】:

属性不会等于 "456" - 它是一个属性,而不是一个字符串。但是,如果您先将其转换为字符串,它将起作用。

var feeds = from feed in xDoc.Descendants("Show")
            where (string)feed.Attribute("Code") == "456"
            select new
            {
                EventDate = feed.Attribute("Date").Value
            };

另一种方法是 int 以确保它是数字:

var feeds = from feed in xDoc.Descendants("Show")
            where (int) feed.Attribute("Code") == 456
            select new
            {
                EventDate = feed.Attribute("Date").Value
            };

编辑:好的,我现在把它作为一个简短但完整的程序来展示它的工作原理。

请注意,您的原始代码仅在“显示”元素具有“日期”属性的情况下才有效 - 它在您的示例 XML 中没有。请注意,它试图从 "Show" 元素而不是 "Event" 元素中获取“日期”。我不确定您在这里真正想做什么,所以我将代码更改为只转换为DateTime?。下面的代码工作并打印 1(即它找到了与代码匹配的单个 Show 元素):

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

public static class Test
{    
    static void Main(string[] args)
    {
        XDocument xDoc = XDocument.Load("shows.xml");
        var feeds = from feed in xDoc.Descendants("Show")
                    where (int) feed.Attribute("Code") == 456
                    select new
                    {
                        EventDate = (DateTime?) feed.Attribute("Date")
                    };

        Console.WriteLine(feeds.Count());
    }
}

如果您实际上试图查找节目中的每个事件日期,则需要另一个“from”子句来迭代节目中的事件:

var events = from feed in xDoc.Descendants("Show")
             where (int) feed.Attribute("Code") == 456
             // We can't use event as an identifier, unfortunately
             from ev in feed.Elements("Event")
             select new
             {
                 EventDate = (DateTime?) ev.Attribute("Date")
             };

【讨论】:

  • 好的,我已经纠正了我的错误,我现在正在评估属性的值,但我仍然没有得到任何结果。正如 'reinierpost' 指出的“不,他正在尝试从 Show="456" 迭代子事件标签。值 "2456" 是一个事件代码。”这是对的。我想返回显示代码“456”的所有日期。所以我需要遍历“事件”元素
  • @kb:查看我的编辑。目前尚不清楚您真正想对日期做什么,但代码找到该节目...
  • 感谢乔恩,您在上面的帖子解决了我的问题!我在想我可能需要使用附加 where 子句来遍历事件日期!谢谢
  • 倒置等式的好技巧。我喜欢。但它也可以使用运算符 == 并且不需要任何技巧,还是我错过了 smthg?
  • @serbrech:不,没有遗漏任何东西。我很傻 :) 会编辑。
【解决方案2】:

改变这一行:

where feed.Attribute("Code").Equals("456")

收件人:

where feed.Attribute("Code").Value.Equals("456")

否则,您会将属性作为对象而不是属性的值进行比较。

【讨论】:

    【解决方案3】:

    这是另一种方法:

       var nodes = xmlFile.Nodes()
      .OfType<XElement>()
        .DescendantNodes()
      .OfType<XElement>()
        .Where(x => x.Name.LocalName == "Event" && x.Attribute("Code").Value.Contains("456"));
    foreach (var node in nodes)
    {
        Console.WriteLine(node.Attribute("Code"));
    }   
    

    【讨论】:

      猜你喜欢
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多