views:

283

answers:

2

I realize this is a repost but I needed to as I can't use LINQ, ( requested in my previous post).

I need to read the woeid from the XML doc below. I need to read and store the data into a string variable so I can query the yahoo weather service.

XML returned by query:

<query yahoo:count="1"
       yahoo:created="2009-12-22T08:30:31Z"
       yahoo:lang="en-US"
       yahoo:updated="2009-12-22T08:30:31Z"
       yahoo:uri="http://query.yahooapis.com/v1/yql?q=select+woeid+from+geo.places+where+text%3D%22farnborough%2C+greater+london%2Cuk%22"&gt;

<diagnostics>
<publiclyCallable>true</publiclyCallable>

<url execution-time="32">
http://where.yahooapis.com/v1/places.q(farnborough%2C%20greater%20london%2Cuk);start=0;count=10
</url>
<user-time>33</user-time>
<service-time>32</service-time>
<build-version>4265</build-version>
</diagnostics>

<results>

<place>
<woeid>19941</woeid>
</place>
</results>
</query>

Can someone suggest how I could do this through XPath or another way which is compatible with the libraries in .net 2.0?

Thanks for the answers. As such I am using the method below, but I get an exception thrown when loading the XML document:

private string getWOEID(string UserLocation, string UserCountry)
{
    string woeID = "";

    if (UserLocation == "farnborough") { UserLocation = "farnborough" + "%2C" + "hampshire"; }

    String reqUrl = "http://query.yahooapis.com/v1/public/yql?q=select%20woeid%20from%20geo.places%20where%20text%3D%22" + UserLocation + "%2C" + UserCountry + "%22&format=xml";

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(reqUrl);
   string woeid = doc.SelectSingleNode("query/results/place/woeid/text()").Value;
    return woeID;


}
+3  A: 

The conventional way:

XmlDocument doc = new XmlDocument();
doc.Load(url);
string woeid = doc.SelectSingleNode("query/place/woeid/text()").Value;

A less conventional way of doing it:

int start = xmlString.IndexOf("<woeid>") + 7;
int end = xmlString.IndexOf("</woeid>", start);
string woeid = xmlString.Substring(start, end - start);

Anyone feel like running a benchmark?

ChaosPandion
-1 for suggesting string manipulation.
John Saunders
I simply offer up 2 options, just as Mark offers up a third. I fail to see how this deserves a down vote.
ChaosPandion
First example doesn't work, needs to fix the Xpath: string woeId = doc.SelectSingleNode("query/results/place/woeid/text()").Value;
Badaro
Offering a bad option deserves a downvote. Using string manipulation on XML ignores handling of special characters, and XML rules in general, and will almost certainly cause a novice to XML to screw up.
John Saunders
Thanks for the heads up Badaro. I rarely use text nodes but in this case it works out quite nice.
ChaosPandion
John, I notice you have almost 600 down votes so I think you might be a little click happy. I clearly label the more conventional matter and offer up another (arguable sufficient for a quick and dirty app) option to keep things interesting.
ChaosPandion
@ChaosPandion: I'm not in this for the votes. I've seen too many occasions where developers new to XML use string manipulation instead of learning the XML APIs. This very often leads to disaster, and certainly leads to them not learning a very valuable tool. The downvote is warranted.
John Saunders
+2  A: 

I'll have another go at this, using ChaosPandion's post as a starting point:

    XmlDocument doc = new XmlDocument();
    using (XmlTextReader tr = new XmlTextReader(new StringReader(xmlString)))
    {
        tr.Namespaces = false;
        doc.Load(tr);
    }
    string woeId = doc.GetElementsByTagName("woeid")[0].InnerText;

Notice here that I'm deliberately ignoring namespaces here since you don't need them for what you are trying to do.

Mark Byers
What are the performance considerations when using GetElementsByTagName over an XPath query?
ChaosPandion
-1 for using `XmlTextReader`, which is deprecated. use `XmlReader.Create` instead.
John Saunders
@John: He only used it to ignore the namespaces, though. Is there a way to do that with XmlReader.Create?
Badaro
Ignoring namespaces is a bad idea. Learn to understand them instead.
John Saunders
Please John tell us why ignoring something you don't care about is bad.
ChaosPandion
Ignoring something because you're too lazy to learn how to use is it bad. And how do you know you won't care about it tomorrow? There's nothing inherent in the problem domain that says namespaces should be ignored. It's purely a matter of the current implementation, which will change as soon as the (extensible) markup changes. Doing it properly, with the namespaces, will still work. Being lazy will break.
John Saunders
@John Saunders: While I appreciate your efforts to improve the quality of the answers here, I don't like the fact that you downvote every answer given here, but then don't post anything yourself and then claim that is *we* who are being lazy. If you think you can do better, post your code please.
Mark Byers
+1 because John -1 for a weird reason
Spooks