Hey everyone,

so I have this project for windows phone i have to do and I have to put some pins on a bing map, but in order to do that I make an API request to google for google places. I get back an XML file and it's like this

<?xml version="1.0" encoding="UTF-8"?>
<PlaceSearchResponse>
 <status>OK</status>
 <result>
  <name>Tetsuya's</name>
  <type>restaurant</type>
  <type>food</type>
  <type>establishment</type>
  <formatted_address>529 Kent Street, Sydney NSW, Australia</formatted_address>
  <geometry>
   <location>
    <lat>-33.8750460</lat>
    <lng>151.2052720</lng>
   </location>
  </geometry>
  <rating>4.3</rating>
  <icon>http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png</icon>
  <reference>CnRmAAAANRC46osWIWF63JgsOdM2XGk22I0x4HxtfL9F_XWMmF3s-ayUyIwvnySqckNlMreu53OqSrX3YsffYOxQh7PYKV2KzI19EqVcBe50qBwmy_vSXoJ3L6ehFYDJTvpHhwAH3b4BFwM8spTOwjOSMeTqhhIQ3LhryZnC4k2F7nKkT9f-8RoUVBwA9UV-C8hHNZh44YkvVOxxtK0</reference>
  <id>827f1ac561d72ec25897df088199315f7cbbc8ed</id>
 </result>
 <result>
  <name>Quay</name>
  <type>cafe</type>
  <type>bar</type>
  <type>restaurant</type>
  <type>food</type>
  <type>establishment</type>
  <formatted_address>Upper Level, Overseas Passenger Terminal/5 Hickson Road, The Rocks NSW, Australia</formatted_address>
  <geometry>
   <location>
    <lat>-33.8583790</lat>
    <lng>151.2100270</lng>
   </location>
  </geometry>
  <rating>4.1</rating>
  <icon>http://maps.gstatic.com/mapfiles/place_api/icons/cafe-71.png</icon>
  <reference>CnRiAAAAeNd3Vvz1j9dvz1deiDQWd96zoKYOFMBVhXYbhbZf4A5zfHmMsolsTAH5pd_AJ2jZYOAfCG82yFJLMTMY5-C_Jnic1bsTVud_uTBnJ0JUzD5Q-p0_7_7qYTRfVqBcCKktQ8PGrQquPEl4LfgDa1j3AhIQfkhCpHR9bgfqawWNkbzpqRoUkd7Qatt_OFkX3KKa9K_fxwE2bc4</reference>
  <id>f181b872b9bc680c8966df3e5770ae9839115440</id>
 </result>
 <result>
  <name>Rockpool</name>
  <type>restaurant</type>
  <type>food</type>
  <type>establishment</type>
  <formatted_address>107 George Street, The Rocks NSW, Australia</formatted_address>
  <geometry>
   <location>
    <lat>-33.8597750</lat>
    <lng>151.2085920</lng>
   </location>
  </geometry>
  <rating>4.0</rating>
  <icon>http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png</icon>
<reference>CnRlAAAALuyHKpRN_oLCCfTJZ-uIA7YdJCe3zEhsSf0RZ25GnX6UhQ66gTeVJdGAyfS2bwB3XPvocWSGBfxF-De6bXC3P_Cvezr9kAEW9jBKvazwyyYZoUaZqVwuy4sGlzKOSCse5qDR7snP63sDD1bkV60OGxIQ2zfuqWNJmtiiSXeNFqSgQhoUthzNiDC86p2SIXdpcarNFXRgBLk</reference>
  <id>7beacea28938ae42bcac04faf79a607bf84409e6</id>
  <event>
    <summary>Google Maps Developer Meetup: Rockin' out with the Places API</summary>
    <event_id>7lH_gK1GphU</event_id>
    <url>https://developers.google.com/places</url>
  </event>
 </result>
</PlaceSearchResponse>

My problem here is that using LINQ in C# I can access the <result> nodes and use the name and address values as well as the location, but I cannot manipulate the <type> nodes. Specifically, I have tried to select them and every time the same subnode <type> gets selected even though there might be more than one subnodes <type> and when I put its value in a text block the same value appears again and again. Can somebody please help me differentiate the <type> nodes from one another?

Recommended Answers

All 5 Replies

I don't know about using LINQ for this, but I would do it like this.

            using System.Xml;
            .
            .
            .
            XmlDocument doc = new XmlDocument();
            doc.Load("source.xml");
            // if you have the xml in a string use doc.LoadXml(stringvar)

            XmlNamespaceManager nsmngr = new XmlNamespaceManager(doc.NameTable);
            XmlNodeList results = doc.DocumentElement.SelectNodes("child::result", nsmngr);

            foreach (XmlNode result in results)
            {
                XmlNode namenode = result.SelectSingleNode("name");
                XmlNodeList types = result.SelectNodes("type");
                foreach (XmlNode type in types)
                {
                    Console.WriteLine(type.InnerText);
                }
                XmlNode fmtaddress = result.SelectSingleNode("formatted_address");
            }

I tried doing it with XmlDocument but the clas is not recognized. I'm doing this with XElement now and I'm stuck. Thanks for the quick reply though

Uhm, did you import the System.Xml namespace like I showed?

That was tested against the file you showed and functions fine.

I did import it but nothing changed. Thanks for all your help. I really appreciate it. By the way, I solved my problem. The code is as follows:

  StreamReader sreader = new StreamReader(file.OpenFile("data.xml", FileMode.Open));
            string xml_data = sreader.ReadToEnd();

            int bom_index = xml_data.IndexOf('<');
            if (bom_index > 0)
            { xml_data = xml_data.Remove(0, bom_index); }
            //the above lines are to delete the first characters of the xml 
            //because there is a bug and they appear out of nowhere


            XmlReader reader = XmlReader.Create(sreader);



            XElement data_elements = XElement.Parse(xml_data);
            var results = from element 
                          in data_elements.Elements("result")
                          select element;

            foreach (XElement child_elements in results)
            {
                string lat, lng;
                Pushpin pin = new Pushpin();
                //pin.Tap += new EventHandler<>pin_Tap;

                 lat = child_elements.Element("geometry").Element("location").Element("lat").Value; 

                 lng = child_elements.Element("geometry").Element("location").Element("lng").Value; 

                pin.Location = new GeoCoordinate(Convert.ToDouble(lat), Convert.ToDouble(lng));




                if (child_elements.Element("name") != null)
                { textBlock1.Text = textBlock1.Text + "Name: " + child_elements.Element("name").Value + System.Environment.NewLine; }
                if(child_elements.Element("formatted_address") != null)
                {textBlock1.Text = textBlock1.Text + "Address: " + child_elements.Element("formatted_address").Value + System.Environment.NewLine;}



                foreach (XElement type_node in child_elements.Descendants())
                {
                    if (type_node.Name == "type")
                    { textBlock1.Text = textBlock1.Text + "Type: " + type_node.Value + System.Environment.NewLine; }

                }

                if (child_elements.Element("rating") != null)
                {textBlock1.Text = textBlock1.Text + "Rating: " + child_elements.Element("rating").Value + System.Environment.NewLine + System.Environment.NewLine;}
            }

            //textBlock1.Text = xml_data;
            map.Children.Add(pin);

For your future reference, please look at System.Xml.XPath and the XPathNavigator as it's much easier to use and quite possibly less resource intensive as you use XPath to directly lookup your required XML (not sure how much though) :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.