Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Type expected

Tags:

c#

xml

linq

have the following linq code, trying to parse an xml file to a datatable but i get strange values in the resultant datatable all cell values show as

System.Xml.Ling.XContainer+<GetElements>d_11

Here is my LINQ

            XDocument doc1 = XDocument.Load(@"D:\m.xml");
            var q = from address in doc1.Root.Elements("Address")
                    let name = address.Elements("Name")
                    let street = address.Elements("Street")
                    let city = address.Elements("city")
                    select new
                    {
                        Name = name,
                        Street = street,
                        City = city
                    };

            var xdt = new DataTable();

            xdt.Columns.Add("Name", typeof(string));
            xdt.Columns.Add("Street", typeof(string));
            xdt.Columns.Add("City", typeof(string));

            foreach (var address in q)
            {
                xdt.Rows.Add(address.Name, address.Street, address.City);
            }

            dataGrid1.ItemsSource = xdt.DefaultView;

here is my xml:

<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
  <Address Type="Shipping">
    <Name>Ellen Adams</Name>
    <Street>123 Maple Street</Street>
    <City>Mill Valley</City>
    <State>CA</State>
    <Zip>10999</Zip>
    <Country>USA</Country>
  </Address>
  <Address Type="Billing">
    <Name>Tai Yee</Name>
    <Street>8 Oak Avenue</Street>
    <City>Old Town</City>
    <State>PA</State>
    <Zip>95819</Zip>
    <Country>USA</Country>
  </Address>
</PurchaseOrder>

and here is the result i get! enter image description here

like image 706
user1590636 Avatar asked Dec 08 '22 17:12

user1590636


2 Answers

You forgot to regrieve the inner text of XElements. So you are selecting the whole element with attributes etc. Use this part of code:

var q = from address in doc1.Root.Elements("Address")
let name = address.Element("Name")
let street = address.Element("Street")
let city = address.Element("city")
select new
{
    Name = name.Value,
    Street = street.Value,
    City = city.Value
};
like image 192
Sasha Avatar answered Dec 11 '22 08:12

Sasha


address.Elements("Name") is a collection of all of the elements of type "Name". It so happens that in your case it's a collection of size one, but it's still a collection. You want to get the first item out of that collection (since you know it will be the only one) and then get the text value of that element. If you use Element instead of Elements you'll get the first item that matches, rather than a collection of items.

Now that you have your single element, you also need to get the value of that element, rather than the element itself (which also contains lots of other information in the general case, even though there really isn't anything else interesting about it in this particular case.

var q = from address in doc1.Root.Elements("Address")
        select new
        {
            Name = address.Element("Name").Value,
            Street = address.Element("Street").Value,
            City = address.Element("City").Value
        };
like image 43
Servy Avatar answered Dec 11 '22 08:12

Servy