1

私はこの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>

LINQ-to-XML を使用して、単一の 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 クエリです (文字列変数sourceに含まれています)。

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を使用してログ内のオブジェクトを反復しようとすると。

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'

前もって感謝します。

4

1 に答える 1

3

これは、変数にではなく、オブジェクトlogのコレクションが含まれているためです。次のようなことをしなければなりません:BillingLogBillingItem

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

あるいは、元の意図が単にすべてBillingItemの を選択することであり、それらの親BillingLogを完全に無視する場合は、次のようにクエリを書き直すことができます。

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これにより、すべての の下から選択されたすべての の単純なコレクションが得られますが、BillingLog自体BillingLogは完全に破棄されます。

于 2010-05-16T13:20:15.893 に答える