David Pollard David Pollard - 9 days ago 5
C# Question

Parse Google Maps GeocodeResponse XML and extract values

I'm making a http request to GoogleMaps API and the XML I get back is listed below.

I'm trying to assign the LAT and LON values to a string but I'm getting a "Null Reference Exception" Object reference not set to an instance of an object. on the line "string lat = childnode...

I based my attempt in this question/answer

When I look in the nodeList in the debugger all the details from the XML are in the Results View.

Any Ideas what I'm doing wrong?

Here is the problem code.

// Parse the XML
XmlDocument doc = new XmlDocument();
doc.LoadXml(responseFromServer);

XmlNodeList nodeList = doc.SelectNodes("/*[local-name() = 'GeocodeResponse']/*[local-name() = 'result']");

if (nodeList != null)
{
foreach (XmlNode childNode in nodeList)
{
string lat = childNode.SelectSingleNode("//*[local-name() = 'geometry/location/lat']").InnerText;
string lon = childNode.SelectSingleNode("//*[local-name() = 'geometry/location/lon']").InnerText;
string locationType = childNode.SelectSingleNode("//*[local-name() = 'geometry/location_type']").InnerText;
}
}


Here is an example of the XML that Google Maps Returns

Address changed to protect the innocent :)

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<GeocodeResponse>
<status>OK</status>
<result>
<type>street_address</type>
<formatted_address>48 Johnson Ave, Wiley Park NSW 2195, Australia</formatted_address>
<address_component>
<long_name>48</long_name>
<short_name>48</short_name>
<type>street_number</type>
</address_component>
<address_component>
<long_name>Johnson Avenue</long_name>
<short_name>Johnson Ave</short_name>
<type>route</type>
</address_component>
<address_component>
<long_name>Wiley Park</long_name>
<short_name>Wiley Park</short_name>
<type>locality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Canterbury City Council</long_name>
<short_name>Canterbury</short_name>
<type>administrative_area_level_2</type>
<type>political</type>
</address_component>
<address_component>
<long_name>New South Wales</long_name>
<short_name>NSW</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Australia</long_name>
<short_name>AU</short_name>
<type>country</type>
<type>political</type>
</address_component>
<address_component>
<long_name>2195</long_name>
<short_name>2195</short_name>
<type>postal_code</type>
</address_component>
<geometry>
<location>
<lat>-33.9279554</lat>
<lng>151.0688625</lng>
</location>
<location_type>ROOFTOP</location_type>
<viewport>
<southwest>
<lat>-33.9293044</lat>
<lng>151.0675135</lng>
</southwest>
<northeast>
<lat>-33.9266064</lat>
<lng>151.0702115</lng>
</northeast>
</viewport>
</geometry>
<partial_match>true</partial_match>
<place_id>ChIJkUHpDOe7EmsRGapwFB6s9Dw</place_id>
</result>
</GeocodeResponse>


EDIT:
It is looking to me like I haven't specified the path to the nodes I want correctly.
Not sure what I should change.

Answer

Use a simpler XPath call:

            XmlDocument doc = new XmlDocument();
            doc.Load("google.xml");

            XmlNodeList nodeList = doc.SelectNodes("/*[local-name() = 'GeocodeResponse']/*[local-name() = 'result']");

            if (nodeList != null)
            {
                foreach (XmlNode childNode in nodeList)
                {
                    string lat = childNode.SelectSingleNode("geometry/location/lat").InnerText;
                    string lon = childNode.SelectSingleNode("geometry/location/lng").InnerText;
                    string locationType = childNode.SelectSingleNode("geometry/location_type").InnerText;
                }
            }

Also...the Longitude node is 'lgn' not lon