0

Ok, I have this that does work trying to fetch weather data - this returns the string version of this dictionary:

Loaded following XML {"coord":{"lon":-118.24,"lat":34.05},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":290.19,"pressure":1027,"humidity":17,"temp_min":288.15,"temp_max":292.55},"visibility":16093,"wind":{"speed":1.27,"deg":20.0024},"clouds":{"all":1},"dt":1548269880,"sys":{"type":1,"id":3694,"message":0.0038,"country":"US","sunrise":1548255306,"sunset":1548292515},"id":5368361,"name":"Los Angeles","cod":200}

Code:

string url = "http://api.openweathermap.org/data/2.5/weather?lat=34.05&lon=-118.24&APPID=33710eba6d9c76286241d779ac1a6d9c";

        WWW www = new WWW(url);
        yield return www;
        if (www.error == null)
        {

            Debug.Log("Loaded following XML " + www.text);

I want to get the description under "weather" but cant figure out how. Select single node does not work:

print(xmlDoc.SelectSingleNode("cities/list/item/weather/description/@value").InnerText);

What can I do here?

blue
  • 7,175
  • 16
  • 81
  • 179
  • JSON is not XML. See [this answer](https://stackoverflow.com/a/6620173/880990) to [How can I parse JSON with C#?](https://stackoverflow.com/questions/6620165/how-can-i-parse-json-with-c) – Olivier Jacot-Descombes Jan 23 '19 at 19:52
  • Possible duplicate of [Easiest way to parse JSON response](https://stackoverflow.com/questions/34043384/easiest-way-to-parse-json-response) – Jimenemex Jan 23 '19 at 20:57

1 Answers1

3

What you get there is a JSON string not an XML

{
    "coord":{
        "lon":-118.24,
        "lat":34.05
    },
    "weather":[
        {
            "id":800,
            "main":"Clear",
            "description":"clear sky",
            "icon":"01d"
        }
    ],
    "base":"stations",
    "main":{
        "temp":290.19,
        "pressure":1027,
        "humidity":17,
        "temp_min":288.15,
        "temp_max":292.55
    },
    "visibility":16093,
    "wind":{
        "speed":1.27,
        "deg":20.0024
    },
    "clouds":{
        "all":1
    },
    "dt":1548269880,
    "sys":{
        "type":1,"id":3694,
        "message":0.0038,
        "country":"US",
        "sunrise":1548255306,
        "sunset":1548292515
    },
    "id":5368361,
    "name":"Los Angeles",
    "cod":200
} 

If you want to access only one or some few values of that JSON you should use the SimpleJSON (simply place all required scripts somewhere in your Assets) and do something like

var N = JSON.Parse(www.text);

var weather = N["weather"];

and than since weather is an array ([...]) access the single values like e.g.

var id = weather[0]["id"];

Carefull however because this SimpleJson "hides" incorrect indexes and strings by simply returning null instead of throwing an exception. This makes debugging a bit harder sometimes (but could also be changed within the code of the JSON class code).


There is also e.g. Unity's JsonUtility but it requires that you implement the entire class which is represented by the JSON string. If you do not need all values this might be a lot of overhead when dealing with huge JSONs.

If you need them however (assuming simple types here no enum etc):

[Serializable]
public class JsonData
{
    public Coord coord;
    public Weather[] weather;
    public string base;
    public Main main;
    public int visibility;
    public Wind wind;
    public Clouds clouds;
    public int dt;
    public Sys sys;
    public int id;
    public string name;
    public int cod;
}

[Serializable]
public class Coord
{
    public float lon;
    public float lat;
}

[Serializable]
public class Weather
{
    public int id;
    public string main;
    public string description;
    public string icon;
}

[Serializable]
public class Main
{
    public float temp;
    public int pressure;
    public int humidity;
    public float temp_min;
    public float temp_max;
}

[Serializable]
public class Wind 
{
    public float speed;
    public float deg;
}

[Serializable]
public class Clouds
{
    public int all;
}

[Serializable]
public class Sys
{
    public int type;
    public int id;
    public float message;
    public string country;
    public int sunrise;
    public int sunset;
}

and than do

var wholeData = JsonUtility.FromJson<JsonData>(www.text);
var weather = wholeData.weather;
var id = weather.id;
derHugo
  • 83,094
  • 9
  • 75
  • 115
  • When using `JsonUtility`, I was pretty sure you only need to implement the fields that you want access to and unmapped JSON is ignored. Is this not so? (Admittedly, I've only really used `FromJsonOverwrite()`) – Immersive Jan 24 '19 at 12:31
  • @Immersive I didn't find this in the docs. It only claims the other way round that `If a field of the object is not present in the JSON representation, that field will be left unchanged.` but it doesn't metnion fields that are present in the JSON but not in the object. – derHugo Jan 24 '19 at 14:27