2010-05-07 4 views
1

Я хочу, чтобы linq сохранил мой xml в csv, и у меня проблема o.Проблема с linq-to-xml

Этот кронштейн здесь beacuse без него этот код не отображается (почему?)

<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

Вы получаете ошибку, потому что значение равно null для элементов. Вам нужно использовать .Attribute (""), чтобы получить атрибуты и использовать значение. – Stephan

+0

Не могли бы вы разместить лучшее подмножество вашего xml-файла, чтобы мы могли попробовать и дать вам ответ? Конечно, Стефан прав, вам нужно использовать метод Attribute (""), но вам также нужно проверить, является ли результат нулевым, прежде чем получить значение, поэтому исключение вашей ссылки на объект ... –

ответ

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

Отель не в вашем xml нигде, поэтому его нужно будет отрегулировать. Обычно я рекомендую вам вытаскивать каждый элемент один раз и проверять нули, а не натягивать регионы 3 раза, как я сделал здесь.

+0

, если атрибут не является установленный на узле, результат c.Attribute() будет пустым, а вызов .Value будет генерировать исключение. Кроме того, приведение в строку не требуется, поскольку значение уже возвращается как строка. –

+0

Мужчины, спасибо! Я в твоем долге. – user278618

+0

@Stephane Вы совершенно правы. Что касается нулевой проблемы, я просто дал быстрое решение. Очевидно, вы сначала захотите сначала проверить значение null, но это станет основным намерением. Литье струн для моей легкости чтения. Мне нравится быть в состоянии легко увидеть, с каким типом я имею дело в выражении select. – Stephan

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(); 
Смежные вопросы