2010-11-24 7 views
4

私は以下のようなXMLファイルを持っている:内部ノードによる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が必要trade_info内部ノードから抽出する必要があります。

だから、最初は私がこれを考えていた:

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

しかし、動作するようには思えないし、それをデバッグする方法にはわからないイムありません。

私が得た最初のエラーから、ヌルエクスプレッションは、一部のクライアントが全くtrade_infoを持っていないので、node.Descendants("trade_info")から来ている可能性があります。

私はまた、いくつかから来ている信じて:

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

のように、時には彼らは、リストまたはbuy_price_rate上のアイテムを持っていけません。

  • は、どのようにそれがnullで天気を私は私のクエリ 以内に確認するか、または確保するためではない、それ
  • は私のクエリは、私が欲しいもののためにOKですか?
  • 変更する必要はありますか?アドバイス?

答えて

3

あなたもこれを行うことができます....

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を選択しました)

2

タイプXElementで、あなたはidのような

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

XNameを使用して選択することができなければならないあなたの価値ドキュメントは、あなただけの文字列を使用することができる必要はありませんが、いくつかの上で、あなたのXMLが名前空間を持っている場合に便利です要素。

+0

私のドキュメントは 'XDocument doc = XDocument.Load(file);'です。 – Prix

+0

コードやXMLを投稿する場合は、テキストエディタでこれらの行をハイライト表示し、エディタツールバーの[コード]ボタン(101 010)をクリックして、フォーマットや構文を強調表示してください! –

2

あなたはにクエリの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を追加する必要があります)

+0

XPathを使用しないでヌル検証を使用するだけでうまく動作しましたが、XPathを使用する方が簡単です。ありがとう。 – Prix

+0

「n.Element( "tab_list")のような構造で、要素( "data")。要素( "tab")。Value'私は、方法の各段階でnullをチェックするのは、 XPathを使用する – Carson63000

関連する問題