代码之家  ›  专栏  ›  技术社区  ›  billmaya

如何迭代Linq to XML查询返回的对象集合?

  •  1
  • billmaya  · 技术社区  · 15 年前

    我有这个XML:

    <BillingLog>
      <BillingItem>
        <date-and-time>2003-11-04</date-and-time>
        <application-name>Billing Service</application-name>
        <severity>Warning</severity>
        <process-id>123</process-id>
        <description>Timed out on a connection</description>
        <detail>Timed out after three retries.</detail>
      </BillingItem>
      <BillingItem>
        <date-and-time>2010-05-15</date-and-time>
        <application-name>Callback Service</application-name>
        <severity>Error</severity>
        <process-id>456</process-id>
        <description>Unable to process callback</description>
        <detail>Reconciliation timed out after two retries.</detail>
      </BillingItem>
    </BillingLog>
    

    我希望使用LinqToXML将其投影到包含在单个BillingLog对象中的BillingItem对象集合中。

    public class BillingLog
    {
        public IEnumerable<BillingItem> items { get; set; }
    }
    
    public class BillingItem
    {
        public string Date { get; set; }
        public string ApplicationName { get; set; }
        public string Severity { get; set; }
        public int ProcessId { get; set; }
        public string Description { get; set; }
        public string Detail { get; set;}       
    }
    

    这是我用来投影XML(包含在字符串变量中)的LINQ查询 来源 )

    XDocument xdoc = XDocument.Parse(source);
    
    var log = 
        from i in xdoc.Elements("BillingLog")
        select new BillingLog
        {
            items =
                from j in i.Descendants("BillingItem")
                select new BillingItem
                {
                    Date = (string)j.Element("date-and-time"),
                    ApplicationName = (string)j.Element("application-name"),
                    Severity = (string)j.Element("severity"),
                    ProcessId = (int)j.Element("process-id"),
                    Description = (string)j.Element("description"),
                    Detail = (string)j.Element("detail")
                }
        };
    

    当我尝试在 日志 使用前述方法。

    foreach (BillingItem item in log)
    {
    Console.WriteLine ("{0} | {1} | {2} | {3} | {4} | {5}", 
                        item.Date, item.ApplicationName, 
                        item.Severity, item.ProcessId.ToString(), 
                        item.Description, item.Detail);
    }   
    

    我从LinqPad收到以下错误消息。

    Cannot convert type 'UserQuery.BillingLog' to 'UserQuery.BillingItem'
    

    事先谢谢。

    1 回复  |  直到 15 年前
        1
  •  3
  •   Fyodor Soikin    15 年前

    那是因为你的 log 变量包含的集合 BillingLog 对象,而不是 BillingItem . 你必须做如下的事情:

    foreach( BillingLog l in log )
    {
        foreach( BillingItem item in l.items )
        {
            Console.WriteLine( ... );
        }
    }
    

    或者,如果您最初的目的是选择全部 比林项 S,无视父母 广告日志 完全可以这样重写查询:

    var log = 
            from l in xdoc.Elements("BillingLog")
            from j in l.Descendants("BillingItem")
            select new BillingItem
            {
                Date = (string)j.Element("date-and-time"),
                ApplicationName = (string)j.Element("application-name"),
                Severity = (string)j.Element("severity"),
                ProcessId = (int)j.Element("process-id"),
                Description = (string)j.Element("description"),
                Detail = (string)j.Element("detail")
            }
    

    这会给你一个简单的收藏 BillingItems 从“全部”下选择 广告日志 S,而 广告日志 S本身将被完全丢弃。