1

I am trying to read a complex XML file using LinQ.

The XML file has a lot of levels, how can get all value in one ILIST<> . there are more tags in items.enter code here

The XML has the following syntax:

<root>
  <items>
    <index_0>
      <product_id>19</product_id>
      <menu_rank>2</menu_rank>
      <menu_country>Guatemala</menu_country>
      <menu_country_code>502</menu_country_code>
      <menu_country_abrv>GT</menu_country_abrv>
      <menu_carrier>TIGO</menu_carrier>
      <menu_value>7.0</menu_value>
    </index_0>
    <index_1>
      <product_id>20</product_id>
      <menu_rank>2</menu_rank>
      <menu_country>Guatemala</menu_country>
      <menu_country_code>502</menu_country_code>
      <menu_country_abrv>GT</menu_country_abrv>
      <menu_carrier>TIGO</menu_carrier>
      <menu_value>10.0</menu_value>
    </index_1>
    <index_2>
      <product_id>21</product_id>
      <menu_rank>2</menu_rank>
      <menu_country>Guatemala</menu_country>
      <menu_country_code>502</menu_country_code>
      <menu_country_abrv>GT</menu_country_abrv>
      <menu_carrier>TIGO</menu_carrier>
      <menu_value>14.0</menu_value>
    </index_2>
  </items>
</root>

I have tried this approach but without success :

var chartrate = from a in xmlDoc.Descendants("items")
                select new 
                {
                  sub_id = a.Element("product_id").Value,
                  product = a.Element("menu_rank").Value,
                  description = a.Element("menu_country").Value
                } ;

Any suggestions?

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
Letoncse
  • 702
  • 4
  • 15
  • 36
  • Trying to embed data in your element names (`index_0`, `index_1`, ...) is going to cause you problems. Change it to something like `` if you can. – Dour High Arch May 23 '13 at 17:45

4 Answers4

0

The biggest problem I see with this is that nither product_id, menu_rank, nor menu_country are elements of items

What is probably the best way to fix this is actually to change the XML schema if you can so that it actually represents a list of items elements.

<root>
 <items>
   <product_id>19</product_id>
   <menu_rank>2</menu_rank>
   <menu_country>Guatemala</menu_country>
   <menu_country_code>502</menu_country_code>
   <menu_country_abrv>GT</menu_country_abrv>
   <menu_carrier>TIGO</menu_carrier>
   <menu_value>7.0</menu_value>
 </items>
 <items>
   <product_id>20</product_id>
   <menu_rank>2</menu_rank>
   <menu_country>Guatemala</menu_country>
   <menu_country_code>502</menu_country_code>
   <menu_country_abrv>GT</menu_country_abrv>
   <menu_carrier>TIGO</menu_carrier>
   <menu_value>10.0</menu_value>
 </items>
 <items>
   <product_id>21</product_id>
   <menu_rank>2</menu_rank>
   <menu_country>Guatemala</menu_country>
   <menu_country_code>502</menu_country_code>
   <menu_country_abrv>GT</menu_country_abrv>
   <menu_carrier>TIGO</menu_carrier>
   <menu_value>14.0</menu_value>
 </items>
</root>

after you do that, you can probably rename items to item in both your xml and your c#

0

This should works:

using System.Xml.XPath;
...

var chartrate = from a in xmlDoc.XPathSelectElements ("/root/items/*")

                     select new 
                     {
                         sub_id = a.Element("product_id").Value,
                         product = a.Element("menu_rank").Value,
                         description = a.Element("menu_country").Value

                     };

The XPath query select all elements, whatever the name it has (see the *) under the /root/items element

Steve B
  • 36,818
  • 21
  • 101
  • 174
0

This should work

var result = X.Element("root")
                .Element("items")
                .Elements().Where(E => E.Name.ToString().Contains("index"))
                .Select(E => new { Id = E.Element("product_id").Value, Country = E.Element("menu_country").Value });

You should look at Sam I am's answer and try to modify your XML if possible.

arunlalam
  • 1,838
  • 2
  • 15
  • 23
0

You just need another level of indirection to retrieve your Index_N elements:

XElement xmlDoc = XElement.Parse(xml);
var chartrate = 
    from a in xmlDoc.Descendants("items").Elements()
    select new 
    {
        sub_id = a.Element("product_id").Value,
        product = a.Element("menu_rank").Value,
        description = a.Element("menu_country").Value
    };

chartrate.Dump();

In LinqPad, this yields:

sub_id product description 
19 2 Guatemala 
20 2 Guatemala 
21 2 Guatemala 
Scott Jones
  • 2,880
  • 13
  • 19