简体   繁体   中英

XElement Sequence contains no elements why?

Here is the XML I am querying:

<GeocodeResponse>
  <status>OK</status>
  <result>
    <type>street_address</type>
    <formatted_address>264 Mugga Ln, Canberra ACT, Australia</formatted_address>
    <address_component>
      <long_name>264</long_name>
      <short_name>264</short_name>
      <type>street_number</type>
    </address_component>
    <address_component>
      <long_name>Mugga Lane</long_name>
      <short_name>Mugga Ln</short_name>
      <type>route</type>
    </address_component>
    <address_component>
      <long_name>Canberra</long_name>
      <short_name>Canberra</short_name>
      <type>colloquial_area</type>
      <type>locality</type>
      <type>political</type>
    </address_component>
    <address_component>
      <long_name>Australian Capital Territory</long_name>
      <short_name>ACT</short_name>
      <type>administrative_area_level_1</type>
      <type>political</type>
    </address_component>
  </result>
</GeocodeResponse>

And here is my C# code:

XElement localityname = xml.Element("result").Elements("address_component")
                           .Where(a => a.Element("type").Value == "locality")
                           .First().Element("long_name");

In most cases, the same/similar XML works fine and I get a value from my query.

What I'm looking for (and works most of the time) is the word "Canberra".

But why does this XML crash with "Sequence contains no elements"???

You have multiple type nodes in the xml, so you have to do like this using XDocument :

XDocument xdoc = XDocument.Parse(XML);

    var element = xdoc.Descendants("result").Descendants("address_component")
                      .Where(x=>x.Descendants("type").Any(y=> y.Value == "locality"))
                      .First().Element("long_name");

I have made a working Fiddle example

But if the element may exist or may not in the xml, then consider using FirstOrDefault() , as it will not throw exception if no element is found matching the criteria of predicate:

var element = xdoc.Descendants("result").Descendants("address_component")
                          .Where(x=>x.Descendants("type").Any(y=> y.Value == "locality"))
                          .FirstOrDefault();

 if(element !=null)
 {
   var val = element.Element("long_name").Value;
 }

If xml is your XDocument , then you are ignoring the GeocodeResponse element.

This query would probably be more forgiving (returning null if the element you're looking for isn't present):

var name = (string)doc.Descendants("address_component")
    .Where(e => (string)e.Element("type") == "locality")
    .Select(e => e.Element("long_name"))
    .SingleOrDefault();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM