Find XElement by Attribute value

2019-04-22 21:58发布

问题:

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:

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.



回答2:

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.