代码之家  ›  专栏  ›  技术社区  ›  Prix Winteroo

用内部节点解析XML?

  •  4
  • Prix Winteroo  · 技术社区  · 15 年前

    我有一个XML文件,如下所示:

     <clients>
      <client>
        <id>YYYY</id>
        <name>XXXX</name>
        <desc>ZZZZ</desc>
        <trade_info>
          <tab_list>
           <data>
             <tab>book 123</tab>
           </data>
           <data>
             <tab>cook 321</tab>
           </data>
          </tab_list>
          <buy_price_rate>200</buy_price_rate>
        </trade_info>
      </client>
     </clients>
    

    我需要从中提取 id, name, desc 从内部节点交易信息 data/tab, buy_price_rate .

    所以最初我想:

        var query = from node in doc.Descendants("client")
                    select new
                    {
                        client = new
                        {
                            Id = node.Element("id").Value,
                            Name = node.Element("name").Value,
                            Desc = node.Element("desc").Value
                        },
    
                        trade = from n in node.Descendants("trade_info")
                                   select new
                                   {
                                       Id = n.Element("tab_list").Element("data").Element("tab").Value,
                                       Buy = n.Element("buy_price_rate").Value
                                   }
                    };
    
            foreach (var item in query)
            {
                writeXML.WriteStartElement("tradelist_template");
                writeXML.WriteAttributeString("client_id", item.client.Id);
                foreach (var trade in item.trade)
                {
                    writeXML.WriteStartElement("tradelist");
                    writeXML.WriteAttributeString("item_id", trade.Id);
                    writeXML.WriteEndElement();
                }
                writeXML.WriteEndElement();
            }
    

    但它似乎不起作用,我不知道如何调试它。

    从我得到的第一个错误,我相信它可能来自 node.Descendants("trade_info") 因为有些客户根本没有交易信息。

    我也相信有一些来自:

    Id = n.Element("tab_list").Element("data").Element("tab").Value,
    Buy = n.Element("buy_price_rate").Value
    

    因为有时他们没有在清单上的项目或购买价格。

    • 如何在查询中检查 它是无效的还是不安全的
    • 我的问题可以满足我的要求吗?
    • 我该换什么?建议?
    3 回复  |  直到 15 年前
        1
  •  3
  •   Tim Jarvis    15 年前

    你也可以这样做。。。。

      var list = from item in doc.Descendants("client")
                 let tradeinfoelement = item.Element("trade_info")
                 select new
                 {
                   Client = new
                   {
                     Id = (string)item.Element("id"),
                     Name = (string)item.Element("name"),
                     Desc = (string)item.Element("desc")
                   },
                   TradeInfo = new
                   {
                     BuyPrice = tradeinfoelement.Element("buy_price_rate")  != null ? (int?)tradeinfoelement.Element("buy_price_rate") : null,
                     Tabs = tradeinfoelement.Descendants("tab") != null ? tradeinfoelement.Descendants("tab").Select(t => (string)t).ToList() : null
                   }
                 };
    

    主要的事情是映射出包装类的外观,并计算出在没有要映射的特定属性的数据的情况下,默认值应该是什么。(在本例中,我选择了nulls)

        2
  •  2
  •   marc_s MisterSmith    15 年前

    你的价值单据应该是 XElement 然后你可以选择 id 喜欢

    var query = from el in doc.Descendants(XName.Get("id"))
     select el.Value;
    

    使用 XName 不需要只使用字符串,但如果xml在某些元素上具有命名空间,则很有用。

        3
  •  2
  •   Carson63000    15 年前

    你能换一下吗 trade 查询的一部分:

    trade = from n in node.Descendants("trade_info")
      select new
      {
        Id = (n.XPathSelectElement("tab_list/data/tab") == null) ? null : n.XPathSelectElement("tab_list/data/tab").Value,
        Buy = (n.Element("buy_price_rate") == null) ? null : n.Element("buy_price_rate").Value
      }
    

    ..?

    (您需要添加 using System.Xml.XPath )