views:

717

answers:

2

Hi all,

I have a collection of IEnumerables and each one has a different attribute values that corresponds to a different property on my business object. Here is a sample of the XML that I am querying against:

  <SimpleData name="zip">60004</SimpleData>
  <SimpleData name="name">ARLINGTON HEIGHTS</SimpleData>
  <SimpleData name="state">IL</SimpleData>
  <SimpleData name="countyname">COOK</SimpleData>
  <SimpleData name="lat">42.1121336684356</SimpleData>
  <SimpleData name="lon">-87.9736682731814</SimpleData>

I think my linq2xml lambda is close (after searching MSDN and SO) but I can't seem to tweak it just right:

string cityName = simpleData.Where(a => a.Attribute("name").Value == "name").Select(a => a.Value).ToString();

The value of cityName get's assigned to "System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String]" instead of ARLINGTON HEIGHTS

Any suggestions? Thanks

+1  A: 
string cityName = (simpleData.Where(a => a.Attribute("name").Value == "name")
                  .Select(a => a.Value)).FirstOrDefault();

or

(from x in simpleData
where x.Attribute("name").Value == "name"
select x.Value).FirstOrDefault()

which returns an IEnumerable<string> (Linq extension methods almost always return collections and not single instances) containing all element values whose name attribute equals name. Then we take the first one, or null if its empty.

Also, that XML is horrendous and should be shot.

Will
+1 for that XML should be shot!
Dennis Palmer
I would suggest using `(string)Attribute("name")` over `Attribute("name").Value` - it's the same thing, except that it does a null-check first. Since `Attribute()` returns `null` when no attribute with such name exits on an element, the first such element would trigger a `NullReferenceException` in the query as currently written.
Pavel Minaev
Damnit, I knew it was just one little thing I was missing, adding FirstOrDefault did it. Thanks.Not much I can do about the XML, it's a 3rd party data import source.
Justin
1) Buy a book on XML. Any book. 2) Locate 3rd party. 3) Beat them bloody with said book.
Will
That's not horrendous XML, it's just mildly annoying. "Horrendous" is when you have gems like `<order1>...</order1><order2>...</order2>...`. Or how about `<name_of_entity_encoded_in_tag>...</name_of_entity_encoded_in_tag>`?
Pavel Minaev
Pav, delete your comment. Don't give ANYBODY ANY HINT that such evil is even possible!
Will
A: 

If you have the XML:

<SimpleDataList>
   <SimpleData name="zip">60004</SimpleData>  
   <SimpleData name="name">ARLINGTON HEIGHTS</SimpleData>  
   <SimpleData name="state">IL</SimpleData>  
   <SimpleData name="countyname">COOK</SimpleData>  
   <SimpleData name="lat">42.1121336684356</SimpleData>  
   <SimpleData name="lon">-87.9736682731814</SimpleData>
</SimpleDataList>

loaded in the XElement/XDocument SimpleDataList, you can query with XPath:

SimpleDataList.XPathSelectElement(@"//SimpleDataList/SimpleData[@Name=""name""]");

But I'm not sure if you have an XElement to start with or a simple IEnumerable... In any case.. i figured I'll mention XPath in case it helps you.

Nestor
It doesn't make much sense to use XPath to query `XDocument`, since it's specifically tailored to LINQ. XPath is going to be slightly slower, too (because it's a string that has to be parsed first).
Pavel Minaev