简体   繁体   中英

Need help parsing XML feed in Windows Phone

I have an XML feed that I've retrieved via httpwebrequest, and I'm having problems parsing the feed since its unlike the times I've tried this in the past. So far I have the url http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni&r=N

which I've stored in

 XDocument doc = XDocument.Parse(feedString);

And I know that when I've dumped that all in a listbox for debugging purposes, I get everything there, I'm just having problems parsing the feed:

<body copyright="All data copyright San Francisco Muni 2012.">
<route tag="N" title="N-Judah" color="003399" oppositeColor="ffffff" latMin="37.7601699" latMax="37.7932299" lonMin="-122.5092" lonMax="-122.38798">
<stop tag="5240" title="King St & 4th St" lat="37.7760599" lon="-122.39436"   stopId="15240"/>
<stop tag="5237" title="King St & 2nd St" lat="37.7796199" lon="-122.38982" stopId="15237"/>
<stop tag="7145" title="The Embarcadero & Brannan St" lat="37.7846299" lon="-122.38798" stopId="17145"/>
<stop tag="4510" title="Embarcadero Folsom St" lat="37.7907499" lon="-122.3898399" stopId="14510"/>
<stop tag="5629" title="Tunnel Entry Point Inbound Nea" lat="37.79279" lon="-122.39126" stopId="15629"/>

And so on and so on

I'd like to store each attribute in each stop tag into an array, but I'm completely stumped as to how I'd begin even.

Thanks

Update: I think I got it to work on that first msdn link, but this only gets the first line:

 using (XmlReader reader = XmlReader.Create(new StringReader(feed)))
        {
            reader.ReadToFollowing("stop");
            reader.MoveToFirstAttribute();
            string tag = reader.Value;


            reader.MoveToNextAttribute();
            string title = reader.Value;

            reader.MoveToNextAttribute();
            string lat = reader.Value;

            reader.MoveToNextAttribute();
            string lon = reader.Value;


        }

How would I loop through each stop with that code above?

Thanks

EDIT: #2

This loop works, but keeps showing the first row of stop attributes:

using (XmlReader reader = XmlReader.Create(new StringReader(feed)))
           {
               reader.ReadToFollowing("stop");
               while (reader.MoveToNextAttribute())
               {

               // Move the reader back to the element node.



                   //reader.ReadToFollowing("stop");
                   reader.MoveToFirstAttribute();
                   string tag = reader.Value;
                   MessageBox.Show(tag);

                   reader.MoveToNextAttribute();
                   string title = reader.Value;
                   MessageBox.Show(title);
                   reader.MoveToNextAttribute();
                   string lat = reader.Value;
                   MessageBox.Show(lat);
                   reader.MoveToNextAttribute();
                   string lon = reader.Value;
                   MessageBox.Show(lon);


               }
               reader.MoveToElement();
           }

I feel like I'm so close to figuring it out.

Here is a complete solution with the help of Linq. Just see what result contains

using (WebClient w = new WebClient())
{
    string xml = w.DownloadString("http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni&r=N");
    XDocument xDoc = XDocument.Parse(xml);
    var result = xDoc.Descendants("stop")
                    .Select(n => new
                    {
                        Tag = (string)n.Attribute("tag"),
                        Title = (string)n.Attribute("title"),
                        Lat = (string)n.Attribute("lat"),
                        Lon = (string)n.Attribute("lon"),
                        StopId = (string)n.Attribute("stopId")
                    })
                    .ToArray();
}

There are many way to parse XML file. Here is one simple approach:

        XDocument doc = XDocument.Load(feedString);
        var stops = doc.Document.Descendants(XName.Get("route"));
        // Loop over all stops in the XML
        foreach (var stop in stops)
        {

        }

I'm not sure what do you mean by "store each attribute in each stop tag into an array", but I would define a type:

class RouteStop
{   // make setters private and init them in ctor to make it immutable
    public string Tag {get; set;} //maybe int ?
    public string Title {get; set;}
    public double Latitude {get; set;}
    public double Longitude {get; set;}
    public int ID {get; set;}
}

Then define a List of RouteStop

List<RouteStop> routeStops = new List<RouteStop>();

and simply in the create object in foreach loop

foreach (var stop in stops)
{
    var tag = stop.Attribute("tag").Value;
    var title = stop.Attribute("title").Value;
    var long = double.Parse(stop.Attribute("lon").Value, 
                            CultureInfo.InvariantCulture);
    //etc
    routeStops.add(new RouteStop() { Tag = tag } //and so on
}

Here is something you can use:

XmlReader xmlReader = XmlReader.Create("http://webservices.nextbus.com/service/publicXMLFeed?   command=routeConfig&a=sf-muni&r=N");
List<string> aTitle= new List<string>();

// Add as many as attributes you have in your "stop" element

while (xmlReader.Read())
{
 //keep reading until we see your element
 if (xmlReader.Name.Equals("stop") && (xmlReader.NodeType == XmlNodeType.Element))
 {
   string title = xmlReader.GetAttribute("title");
   aTitle.Add(title);

   // Add code for all other attribute you would want to store in list.
  }
}

Finally call the list and based on index you can get all the items.

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