2010-05-07 123 views
1

我想通過linq保存我的xml在csv中,我有問題。linq-to-xml問題

這個支架在這裏怎麼一回事,因爲沒有它,這個代碼不顯示(爲什麼?)

<results> 
    <Countries country="Albania"> 
     <Regions region="Centralna Albania"> 
      <Provinces province="Durres i okolice"> 
       <Cities city="Durres" cityCode="2B66E0ACFAEF78734E3AF1194BFA6F8DEC4C5760"> 
        <IndividualFlagsWithForObjects Status="1" /> 
        <IndividualFlagsWithForObjects Status="0" /> 
        <IndividualFlagsWithForObjects magazyn="2" /> 
       </Cities> 
      </Provinces> 
     </Regions> 
    </Countries> 
    <Countries country="Albania"> 
     <Regions region="Centralna Albania"> 
      <Provinces province="Durres i okolice"> 
       <Cities city="Durres" cityCode="2B66E0ACFAEF78734E3AF1194BFA6F8DEC4C5760"> 
        <IndividualFlagsWithForObjects storage="0" Status="1" /> 
        <IndividualFlagsWithForObjects storage="1" Status="0" /> 
        <IndividualFlagsWithForObjects storage="2" Status="1" /> 
       </Cities> 
      </Provinces> 
     </Regions> 
    </Countries> 
</results> 

我必須指出一個重要的事情: 父節點是 但是當我使用它loaded.Descendants(」結果「)它沒有給我什麼。

XDocument loaded = XDocument.Load(@"c:\citiesxml.xml"); 

// create a writer and open the file 
TextWriter tw = new StreamWriter("c:\\XmltoCSV.txt"); 

// Query the data and write out a subset of contacts 
var contacts = (from c in loaded.Descendants("Countries") 
    select new 
    { 
     Country = (string)c.Attribute("ountry").Value, 
     Region = (string)c.Element("Regions").Attribute("region").Value, 
     Province= c.Element("Regions").Element("Provinces").Attribute("prowincja").Value, 
     City= c.Element("Regions").Element("Provinces").Element("Cities").Attribute("city").Value, 
     Kod = c.Element("Regions").Element("Provinces").Element("Cities").Attribute("cityCode").Value, 
     IndywidualnaFlagaStatus = c.Element("Regions").Element("Provinces").Element("Cities").Element("IndividualFlagsWithForObjects").Attribute("Status"), 
     IndywidualnaFlagaWartosc = c.Element("Regions").Element("Provinces").Element("Cities").Element("IndividualFlagsWithForObjects").Attribute("storage") 
    }).ToList(); 

最後一個問題:

IndywidualnaFlagaWartosc = c.Element("Regions").Element("Provinces").Element("Cities").Element("IndividualFlagsWithForObjects").Attribute("storage") 

給我:

IndywidualnaFlagaWartosc = {storage="0"} (I see this while debugging) 
+1

您會收到錯誤,因爲元素上的值爲空。您需要使用.Attribute(「」)來獲取屬性並在其上使用Value。 – Stephan 2010-05-07 12:53:22

+0

您可以發佈您的XML文件的更好的子集,以便我們可以嘗試並給你一個測試的答案? 當然斯蒂芬是正確的,你需要使用Attribute(「」)方法,但你也需要測試結果是否爲null之前獲取該值,因此您的對象引用異常... – 2010-05-07 12:54:32

回答

4
var contacts = (from c in loaded.Descendants("Countries") 
         select new 
         { 
          Country = (string)c.Attribute("Country").Value, 
          Region = (string)c.Element("Regions").Attribute("region").Value, 
          Province = (string)c.Element("Regions").Element("Provinces").Attribute("province").Value, 
          City = (string)c.Element("Regions").Element("Provinces").Element("Cities").Attribute("city").Value, 
          Hotel = (string)c.Element("Hotels").Attribute("hotel").Value 
         }).ToList(); 

酒店不在任何地方,所以需要進行調整。我通常會建議您將每個項目拉一次,然後檢查是否爲空值,而不是按照我在此處所做的那樣拉動區域3次。

+0

如果屬性不是在節點上設置,c.Attribute()的結果將爲null,調用.Value將拋出異常。也不需要轉換爲字符串,因爲該值已經以字符串形式返回。 – 2010-05-07 12:57:02

+0

男人,謝謝!我在你的債務。 – user278618 2010-05-07 12:58:29

+0

@Stephane你完全正確。就無效問題而言,我只是提供了快速解決方案。顯然你會想先檢查null,但是這會得到基本的意圖。串演員是在那裏爲我的閱讀方便。我喜歡能夠在選擇語句中輕鬆查看我正在處理的類型。 – Stephan 2010-05-07 13:00:05

1

YOUT元素名稱不匹配你的XML剪斷(代碼段中所有的元素都是單數和在LINQ查詢他們是複數(國家 - 國家,地區 - 地區等)

var contacts = (from c in loaded.Descendants("Countries") 
          select new 
          { 
           Country = c.Element("Countries").Value, 
           Region = c.Element("Regions").Value, 
           Province= c.Element("Provinces").Value, 
           City = c.Element("Cities").Value, 
           Hotel = c.Element("Hotels").Value 
          }).ToList(); 
1

您正在請求元素作爲對象,而不是它的值。你的代碼應該是:

var contacts = (from c in loaded.Descendants("Countries") 
       select new 
       { 
        Country = c.Element("Country").Value, 
        Region = c.Element("region").Value, 
        Province= c.Element("province").Value, 
        City = c.Element("city").Value, 
        Hotel = c.Element("hotel").Value 
       }).ToList(); 

但我不確定這會給出任何結果,以及如果我看看你的XML。我猜這應該給你你想要的結果:

var contacts = (from c in loaded.Descendants("Countries") 
       select new 
       { 
        Country = c.Attribute("country").Value, 
        Region = c.Descendants("Regions").FirstOrDefault().Attribute("region")Value, 
        Province= c.Descendants("Provinces").FirstOrDefault().Attribute("province").Value, 
        City = c.Descendants("Cities").FirstOrDefault().Attribute("city").Value, 
        Hotel = c.Descendants("Hotels").FirstOrDefault().Attribute("hotel").Value 
       }).ToList(); 

請注意,這個代碼是相當脆弱的,因爲如果decentant要素之一是缺少,會出現異常。你應該對自己進行微調以獲得你想要的結果。

1

對不起,這個答案不完整。你不會在任何國家,但與下面的代碼獲取值,但它應該是一個很好的起點,所以儘量使用c.Element(),你應該使用c.Attribute()像這樣:

var contacts = (from c in loaded.Descendants("Countries") 
    select new 
    { 
     Country = (string)c.Attribute("country"), 
     Region = (string)c.Attribute("region"), 
     Province = (string)c.Attribute("province"), 
     City = (string)c.Attribute("city"), 
     Hotel = (string)c.Attribute("hotel") 
    }).ToList();