使用内部节点解析 XML?

发布于 2024-10-04 06:54:34 字数 2289 浏览 2 评论 0原文

我有一个如下所示的 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 并从内部节点 trade_info 中提取 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();
        }

但它似乎不起作用,我不确定如何调试它。

从我收到的第一个错误“Null Expectation”开始,我相信它可能来自 node.Descendants("trade_info"),因为有些客户端根本没有 trade_info。

我还相信有一些来自:

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

因为有时他们没有清单上的物品或购买价格。

  • 如何在我的查询中进行检查 它是否为空以保护它
  • 我的查询可以满足我想要的吗?
  • 我应该改变什么?建议?

I have a XML file like the below:

 <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>

I need to extract from it id, name, desc and from the inner node trade_info I need data/tab, buy_price_rate.

So initially I was thinking of this:

    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();
        }

But it does not seem to work and im not sure on how to debug it.

From the first error I got, Null Expection I belive it may be coming from the node.Descendants("trade_info") as some clients have no trade_info at all.

I also belive there is some comming from:

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

As sometimes they dont have items on the list or buy_price_rate.

  • How do I check within my query
    wether it is null or not to secure it
  • Is my query ok for what I want ?
  • What should I change ? Advices ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你げ笑在眉眼 2024-10-11 06:54:34

你也可以这样做......

  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
               }
             };

主要的事情是映射出你的包装类的样子,并计算出你的默认值应该是什么,以防你要映射的特定属性没有数据。 (我在这个例子中选择了null)

you could also do this....

  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
               }
             };

The main thing is to map out what your wrapping class looks like and work out what your defaults should be in case there is no data for the specific property you will map. (I chose nulls in this example)

怪我闹别瞎闹 2024-10-11 06:54:34

您的值文档应为 XElement 类型,然后您可以选择 id,就像

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

使用 XName 一样,不必要,您可以只使用字符串,但在以下情况下很有用:您的 xml 在某些元素上具有名称空间。

Your value doc should of type XElement then you can select id like

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

using XName is not necessary you can just use a string, but is useful if your xml has namespaces on some of the elements.

·深蓝 2024-10-11 06:54:34

您能否将查询的 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
  }

..?

(您需要使用 System.Xml.XPath 添加

Can you change the trade part of your query to:

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
  }

..?

(you'll need to add using System.Xml.XPath)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文