0

I have the following xml file (shortened).As you can see, i want to get the second "maxtempC" Value.

    <data>
      <request>...</request>
      <current_condition>...</current_condition>
      <weather>
        <date>2015-06-12</date>
        <astronomy>...</astronomy>
        <maxtempC>27</maxtempC>
        <maxtempF>80</maxtempF>
        <mintempC>14</mintempC>
        <mintempF>58</mintempF>
        <uvIndex>7</uvIndex>
        <hourly>...</hourly>
        <hourly>...</hourly>
        <hourly>...</hourly>
        <hourly>...</hourly>
      </weather>
      <weather>
        <date>2015-06-13</date>
        <astronomy>...</astronomy>
        <maxtempC>25</maxtempC> //I want this Value
        <maxtempF>77</maxtempF>
        <mintempC>14</mintempC>
        <mintempF>56</mintempF>
        <uvIndex>6</uvIndex>
        <hourly>...</hourly>
        <hourly>...</hourly>
        <hourly>...</hourly>
        <hourly>...</hourly>
      </weather>
    </data>

I have tried it using the following:

  XElement wData = XElement.Load(query);
  string maxtempC2;
  act_maxtempC2 = wData.Elements("weather")
                           .Skip(1)
                           .Take(1)
                           .Elements("maxtempC")
                           .Value;

I have also tried using this:

    act_maxtempC2 = wData.Elements("weather")
                           .Skip(1)
                           .Take(1)
                           .Elements("maxtempC")
                           .Select(o => o.Value);

But in both cases, it gives not the Value of the Node, just a weird string like this: {System.Linq.Enumerable.WhereSelectEnumerableIterator}

I hope you can Help me

JulCode
  • 21
  • 6

2 Answers2

0

Why not just

act_maxtempC2 = wData.Elements("data").ToList()[1].Element("weather").Element("maxtempC");

You take the "s" out of Elements

maraaaaaaaa
  • 7,749
  • 2
  • 22
  • 37
  • That soulution gave me an copiling error wich says that I can't idex[] an expression of type "System.Collections.Generic.IEnumerable" @Andrew taking the "s" out of the second elemnts does not work :/ – JulCode Jun 12 '15 at 12:05
  • It wasnt the "Elements" part that gave you the error, i forgot to cast it to a list before indexing it, try it now – maraaaaaaaa Jun 12 '15 at 12:12
  • It throws an exception, that I have to activate an start index parameter. How can I realize that? – JulCode Jun 12 '15 at 16:32
  • Can you paste the exception – maraaaaaaaa Jun 12 '15 at 16:33
  • I am using the German version of Visual Studio I do not know weather it helps, but i'll try top translate (and ill paste the exception) German Exception: In System.ArgumentOutOfRangeException ist eine Ausnahme vom Typ "mscorlib.dll" aufgetreten, doch wurde diese im Benutzercode nicht verarbeitet. Zusätzliche Informationen: Der Index lag außerhalb des Bereichs. Er muss nicht negativ und kleiner als die Auflistung sein. Translation(Hope it isn't too bad) Further Information: The Index was out of range. It must be not negative and smaller then the listing. – JulCode Jun 12 '15 at 21:00
  • Still the same Exception – JulCode Jun 12 '15 at 21:50
0

This should do the job:

        var value = wData.Elements("weather").Skip(1).Elements("maxtempC").Select(e => e.Value).FirstOrDefault();

The problem with this statement:

        var act_maxtempC2 = wData.Elements("weather")
                               .Skip(1)
                               .Take(1)
                               .Elements("maxtempC")
                               .Select(o => o.Value);

Is that you never actually evaluated the linq query. You need to add, say, FirstOrDefault() to actually retrieve the string value:

        var act_maxtempC2 = wData.Elements("weather")
                               .Skip(1)
                               .Take(1)
                               .Elements("maxtempC")
                               .Select(o => o.Value)
                               .FirstOrDefault();

To clarify, Enumerable.Take(1) doesn't project the enumerable into its first element. Instead, it returns a filtered enumerable containing the first element of the input enumerable. To project to a specific element, use FirstOrDefault() e.g.; ElementAt() is another option.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • Your soultion worked comiling, but as I got through it, act_maxtempC kept on being null. – JulCode Jun 12 '15 at 12:06
  • @JulCode - is `` the [root element](https://en.wikipedia.org/wiki/Root_element) of the `query` XML? – dbc Jun 12 '15 at 17:28
  • @JulCode - is there anything else present in the root element such as one or more [`xmlns` tags](http://stackoverflow.com/questions/1181888/what-does-xmlns-in-xml-mean)? – dbc Jun 12 '15 at 20:58
  • @JulCode - My code works with the example given and with the XML example shown [here](http://www.worldweatheronline.com/api/docs/local-city-town-weather-api.aspx). Suggest you make sure your XML contains what you think by adding a `Debug.WriteLine(wData);` after it's loaded. – dbc Jun 12 '15 at 21:22
  • Checked the wData and its all correct. updatet my XML file, maybe I missed soemthing before – JulCode Jun 12 '15 at 22:10
  • @JulCode - here's a working example: https://dotnetfiddle.net/ce15YM So I'm not sure where your problem is. – dbc Jun 13 '15 at 22:09
  • thanks it worked now! Found my mistake. I declared wData as XDocument not as var. Thanks for your code that brang me to the solution :) – JulCode Jun 14 '15 at 09:57