【问题标题】:How to parse deeply nested using LINQ to XML如何使用 LINQ to XML 解析深度嵌套
【发布时间】:2023-03-06 11:20:01
【问题描述】:

如何使用 LINQ 解析以下 XML?
我需要为每个 OrderOrderCancelled 插入数据库表 OrderNumber, ShipAddress, ShipCity, ShipState
然后在一个单独的表中,我需要从 Returns/Amount 部分插入 OrderId

<!-- language: lang-xml -->
<?xml version="1.0" encoding="utf-8"?>
<OrdersReport Date="2012-08-01">
<Client>
<ClientId>1</ClientId>
  <Orders>
    <Order>
      <OrderNumber>1</OrderNumber>
      <ShipAddress>123 Main St.</ShipAddress>
      <ShipCity>MyCity</ShipCity>
      <ShipState>AZ</ShipState>
    </Order>
    <Order>
      <OrderNumber>2</OrderNumber>
      <ShipAddress>111 Main St.</ShipAddress>
      <ShipCity>OtherCity</ShipCity>
      <ShipState>AL</ShipState>
    </Order>
    <OrderCancelled>
      <OrderNumber>3</OrderNumber>
      <ShipAddress>111 Main St.</ShipAddress>
      <ShipCity>OtherCity</ShipCity>
      <ShipState>AL</ShipState>
    </OrderCancelled>
  </Orders>  
  <Returns>
    <Amount>
      <OrderId>2</OrderId>
      <OrderId>3</OrderId>
    </Amount>
  </Returns> 
</Client>
<Client>
<ClientId>2</ClientId>
<!-- Same Tree structure as Client 1 -->
</Client>
</OrdersReport>

根据收到的回复,我更新了问题。

var doc = XDocument.Load(rootFolder + "Generic.xml");
    var query = doc.Descendants("Order")
                   .Concat(doc.Descendants("OrderCancelled"))
                   .Select(x => new
                   {
                       OrderNumber = (int)x.Element("OrderNumber"),
                       ShipAddress = (string)x.Element("ShipAddress"),
                       ShipCity = (string)x.Element("ShipCity"),
                       ShipState = (string)x.Element("ShipState")
                   });           

    var amount = doc.Descendants("Amount")                         
                  .Select(y => new
                  {
                      OrderId = (int)y.Element("OrderId")
                  });

    foreach (var o in query)
    {
        Console.WriteLine(o.OrderNumber + o.ShipAddress + o.ShipCity);
    }
    foreach (var r in amount)
    {
        Console.WriteLine(r.OrderId);
    }

金额枚举只给了我第一个OrderId,我做错了什么?

【问题讨论】:

  • 发布后颜色出现了 :-) 但还没有缩进。

标签: c# xml linq linq-to-xml


【解决方案1】:

听起来您只想要所有后代 Order/OrderCancelled 元素:

var doc = XDocument.Load("file.xml");
var query = doc.Descendants("Order")
               .Concat(doc.Descendants("OrderCancelled"))
               .Select(x => new {
                           OrderNumber = (int) x.Element("OrderNumber"),
                           ShipAddress = (string) x.Element("ShipAddress"),
                           ShipCity = (string) x.Element("ShipCity"),
                           ShipState = (string) x.Element("ShipState")
                       });

然后您可以遍历结果,这将是一个匿名类型的序列,并执行任何您需要的操作将其插入到数据库中。

【讨论】:

  • 那么,我可以为 Returns 做类似的选择吗?
  • @Picflight:当然可以,不过请注意,您必须在每个 Amount 中获取每个 OrderId 元素。
【解决方案2】:

我认为没有串联是可能的:

var query = from o in xdoc.Descendants("Orders").Elements()
            select new 
            {
                OrderNumber = (int)o.Element("OrderNumber"),
                ShipAddress = (string)o.Element("ShipAddress"),
                ShipCity = (string)o.Element("ShipCity"),
                ShipState = (string)o.Element("ShipState")
            };

【讨论】:

  • 如何满足“对于每个订单和订单取消”?
  • @JonSkeet 抱歉,忘了Elements()
  • 对,这样就可以了——只要Orders从不任何其他元素。
猜你喜欢
  • 2013-06-08
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-29
  • 1970-01-01
相关资源
最近更新 更多