嵌套linq到XML查询

时间:2013-12-29 00:50:10

标签: c# linq linq-to-xml

如何让LINQ循环嵌套的获胜分支?我想循环sum_sweedensum_japan字段。

这是我的XML结构:

<TheAPI>
  <TheResult>
    <command>booksResults</command>
  </TheResult>
  <TheData>
    <books>
      <book id="101495">
        <coupon_close_date>1366030400</coupon_close_date>
        <coupon_local_close_date>1366012400</coupon_local_close_date>
        <book_status id="1">Published</book_status>
        <book_details>
          <book_detail>
            <author>bnvbnvb</author>
            <publisher>nnbnbn</publisher>           
          </book_detail>
        </book_details>
        <deals_breakdowns>
          <deal_breakdown id="1">
            <winning deal="5">
              <sum_sweeden>715.00</sum_sweeden>
              <sum_japan>715.00</sum_japan>
            </winning>
          </deal_breakdown>
          <deal_breakdown id="2">
            <winning>
              <sum_sweeden>100.00</sum_sweeden>
              <sum_japan>100.00</sum_japan>
            </winning>
          </deal_breakdown>
        </deals_breakdowns>
      </book>
      <book id="101417">
        <coupon_close_date>1387684800</coupon_close_date>
        <coupon_local_close_date>1387666800</coupon_local_close_date>
        <book_status id="1">Published</book_status>
        <book_details>
          <book_detail>
            <author>mn xccx cvx</author>
            <publisher>hjgh hg jghjg</publisher>         
          </book_detail>
        </book_details>
        <deals_breakdowns>
          <deal_breakdown id="1">
            <winning>0</winning>
          </deal_breakdown>
          <deal_breakdown id="2">
            <winning>
              <sum_sweeden >100</sum_sweeden>
              <sum_japan >100</sum_japan>
            </winning>
          </deal_breakdown>
        </deals_breakdowns>
      </book>
  </TheData>
</TheAPI>

我能够成功地使用LINQ循环所有book

public class ResultsBookData
{
    public decimal couponCloseDate { get; set; }
    public decimal SumSweeden { get; set; }
    public int BookStatusId { get; set; }
    public string BookStatus { get; set; }
    public string Author { get; set; }
    public string Publisher { get; set; }
    public decimal SumJapan { get; set; }              
}

var result = (from node in books.Elements("book")
              select new ResultsBookData()
              {
                  couponCloseDate = node.SafeValueAsInt("coupon_close_date"),
                  SumSweeden = node.SafeValueAsInt("sum_sweeden"),
                  BookStatusId = node.SafeAttAsInt("book_status", "id"),
                  BookStatus = node.SafeValueAsString("book_status"),
                  Author = node.Element("book_details").HasElements ? node.Element("book_details").Element("book_detail").Element("author").Value : null,
                  Publisher = node.Element("book_details").HasElements ? node.Element("book_details").Element("book_detail").Element("publisher").Value : null,      
                  SumSweeden = node.Element("deals_breakdowns").Element("deals_breakdown").Element("winning").SafeValueAsDecimal("sum_sweeden"),      
                  SumJapan = node.Element("deals_breakdowns").Element("deals_breakdown").Element("winning").SafeValueAsDecimal("sum_japan"),
              }).ToList()

1 个答案:

答案 0 :(得分:0)

首先 - <deals_breakdown>中有几个<deals_breakdowns>个元素。因此,您需要使用Elements("deals_breakdown")选择所有这些内容。第二 - 你需要聚合(汇总)<sum_sweeden>元素值,因为你有SumSweeden属性,它需要单个十进制值,而不是小数的集合:

SumSweeden = node.Element("deals_breakdowns")
                 .Elements("deals_breakdown")
                 .Sum(b => b.Element("winning")
                            .SafeValueAsDecimal("sum_sweeden")),

还要记住,您可以安全地将元素转换为字符串或某些可空类型(bool,int,decimal)。考虑到这一点,您可以摆脱自定义扩展方法并使用以下查询:

from book in books.Elements("book")
let bookStatus = book.Element("book_status")
let bookDetail = book.Elements("book_details").Elements("book_detail").FirstOrDefault()
let winnings = book.Element("deals_breakdowns").Elements("deal_breakdown").Elements("winning")
select new ResultsBookData()
{
    couponCloseDate = (int)book.Element("coupon_close_date"),
    BookStatusId = (int)bookStatus.Attribute("id"),
    BookStatus = (string)bookStatus,
    Author = bookDetail == null ? null : (string)bookDetail.Element("author"),
    Publisher = bookDetail == null ? null : (string)bookDetail.Element("publisher"),
    SumSweeden = winnings.Sum(w => (decimal?)w.Element("sum_sweeden") ?? 0),
    SumJapan = winnings.Sum(w => (decimal?)w.Element("sum_japan") ?? 0)
}

结果:

{
   couponCloseDate: 1366030400.0,
   SumSweeden: 815.00,
   BookStatusId: 1,
   BookStatus: "Published",
   Author: "bnvbnvb",
   Publisher: "nnbnbn",
   SumJapan: 815.00      
},
{
   couponCloseDate: 1387684800.0,
   SumSweeden: 100.0,
   BookStatusId: 1,
   BookStatus: "Published",
   Author: "mn xccx cvx",
   Publisher: "hjgh hg jghjg",
   SumJapan: 100.0
}