1

Sample XML:

<query yahoo:count="1" yahoo:created="2016-03-31T06:43:49Z" yahoo:lang="en-US">
    <results>
        <channel>
            <item>
                <yweather:condition code="28" date="Thu, 31 Mar 2016 08:00 AM SAST" temp="58" text="Mostly Cloudy"/>
            </item>
        </channel>
    </results>
 </query>

Code:

string weburl = "https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28select%20woeid%20from%20geo.places%281%29%20where%20text%3D%22Cape%20Town%22%29&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";

var xml = await new WebClient().DownloadStringTaskAsync(new Uri(weburl));

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

XmlElement root = doc.DocumentElement;

XmlNodeList nodes = root.SelectNodes("//query/results/channel/item");

foreach (XmlNode node in nodes)
{
    MessageBox.Show(node.InnerXml);
}

I have been struggling to just get the temp and text outputed but I can't find way how to, this is as far as I got.

Matthew
  • 11
  • 2

3 Answers3

0

You can access XML attributes from XmlNode.Attributes property :

var condition = doc.SelectSingleNode("/query/results/channel/item/*");
MessageBox.Show(condition.Attributes["text"].Value);
MessageBox.Show(condition.Attributes["temp"].Value);
har07
  • 88,338
  • 12
  • 84
  • 137
  • They are not attributes. The itmes are part of the innnertext. – jdweng Mar 31 '16 at 10:34
  • 2
    @jdweng `text` and `temp` are attributes of `yweather:condition` element : ``. It is either you missed about the XML structure or you don't understand definition of XML attribute. – har07 Mar 31 '16 at 10:40
  • Look at the code carefully : innertext. Attributes are inside angle brackets, not between. – jdweng Mar 31 '16 at 10:45
  • 2
    @jdweng please, look at the code carefully. `` is *self-closing* tag or *empty element*, it doesn't have inner text. Search and read about self-closing tag/empty element if you're not familiar with it : http://stackoverflow.com/questions/35663989/is-this-valid-xml-tagging/35664912#35664912 – har07 Mar 31 '16 at 10:47
  • 2
    I agree with @har07. "text" and "temp" is accessible with the XmlNodeAttributes. – Riaan Mar 31 '16 at 11:21
  • I've never seen attributes inside innertext with xml before. – jdweng Mar 31 '16 at 12:04
  • 1
    dang, you still don't understand it isn't in innertext! It is in innertext in your XML, but not in OP's – har07 Mar 31 '16 at 12:07
0

Try this....

Usings....

using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

Classes....

    [XmlRoot(ElementName = "condition", Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
    public class Condition
    {
        [XmlAttribute(AttributeName = "yweather", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Yweather { get; set; }
        [XmlAttribute(AttributeName = "code")]
        public string Code { get; set; }
        [XmlAttribute(AttributeName = "date")]
        public string Date { get; set; }
        [XmlAttribute(AttributeName = "temp")]
        public string Temp { get; set; }
        [XmlAttribute(AttributeName = "text")]
        public string Text { get; set; }
    }

    [XmlRoot(ElementName = "item")]
    public class Item
    {
        [XmlElement(ElementName = "condition", Namespace = "http://xml.weather.yahoo.com/ns/rss/1.0")]
        public Condition Condition { get; set; }
    }

    [XmlRoot(ElementName = "channel")]
    public class Channel
    {
        [XmlElement(ElementName = "item")]
        public Item Item { get; set; }
    }

    [XmlRoot(ElementName = "results")]
    public class Results
    {
        [XmlElement(ElementName = "channel")]
        public Channel Channel { get; set; }
    }

    [XmlRoot(ElementName = "query")]
    public class Query
    {
        [XmlElement(ElementName = "results")]
        public Results Results { get; set; }
        [XmlAttribute(AttributeName = "yahoo", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Yahoo { get; set; }
        [XmlAttribute(AttributeName = "count", Namespace = "http://www.yahooapis.com/v1/base.rng")]
        public string Count { get; set; }
        [XmlAttribute(AttributeName = "created", Namespace = "http://www.yahooapis.com/v1/base.rng")]
        public string Created { get; set; }
        [XmlAttribute(AttributeName = "lang", Namespace = "http://www.yahooapis.com/v1/base.rng")]
        public string Lang { get; set; }
    }

Code...

        XmlDocument xmlDocument = new XmlDocument();
        try
        {
            xmlDocument.Load("https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28select%20woeid%20from%20geo.places%281%29%20where%20text%3D%22Cape%20Town%22%29&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys");

            string XMLxmlDocument = xmlDocument.InnerXml.ToString();
            byte[] BUFXML = ASCIIEncoding.UTF8.GetBytes(XMLxmlDocument);
            MemoryStream ms1 = new MemoryStream(BUFXML);

            XmlSerializer DeserializerPlaces = new XmlSerializer(typeof(Query));//, new XmlRootAttribute("Query"));
            using (XmlReader reader = new XmlTextReader(ms1))
            {
                Query dezerializedXML = (Query)DeserializerPlaces.Deserialize(reader);

                string temp = dezerializedXML.Results.Channel.Item.Condition.Temp;
                string text = dezerializedXML.Results.Channel.Item.Condition.Text;

            }// Put a break-point here, then mouse-over temp and text, you should have you values (dezerializedXML contains the entire object)
        }
        catch (System.Exception)
        {
            throw;
        }
Monty
  • 1,534
  • 2
  • 10
  • 12
-1

I used xml linq along with Regex. I had to fix issues with your xml. I think the main issue was the namespaces.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                "<Root xmlns:yahoo=\"abc\" xmlns:yweather=\"def\">" +
                "<query yahoo:count=\"1\" yahoo:created=\"2016-03-31T06:43:49Z\">" +
                  "yahoo:lang=\"en-US\"><results>" +
                    "<channel>" +
                      "<item>" +
                        "<yweather:condition>" +
                          "code=\"28\" date=\"Thu, 31 Mar 2016 08:00 AM SAST\" temp=\"58\" text=\"Mostly Cloudy\"/>" +
                        "</yweather:condition>" +
                      "</item>" +
                    "</channel>" +
                  "</results>" +
                "</query>" +
                "</Root>";

            XDocument doc = XDocument.Parse(xml);

            string innertext = doc.Descendants().Where(x => x.Name.LocalName == "condition").Select(y => y.Value).FirstOrDefault();
            string pattern = "\\s?(?'name'[^=]+)=\"(?'value'[^\"]+)\"";
            MatchCollection matches = Regex.Matches(innertext, pattern);
            foreach (Match match in matches)
            {
                Console.WriteLine("Name : {0}, Value : {1}", match.Groups["name"].Value, match.Groups["value"].Value);
            }
            Console.ReadLine();
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • You made up your own XML! This code won't work against OP's XML – har07 Mar 31 '16 at 10:52
  • Instead of creating your own XML, you can get the actual, well-formed XML through the link that OP accessed : https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28select%20woeid%20from%20geo.places%281%29%20where%20text%3D%22Cape%20Town%22%29&format=xml&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys – har07 Mar 31 '16 at 11:05
  • Did you look at the URL page? – jdweng Mar 31 '16 at 12:01
  • I didn't create my own xml. Just added a root so I could add the missing namespaces. The code I posted should work with any well formed xml. – jdweng Mar 31 '16 at 12:03
  • In firefox the steps would be : open the link -> right click -> view page source – har07 Mar 31 '16 at 12:06