Accéder aux membres des éléments dans un JSONArray avec Java

122

Je commence juste à utiliser json avec java. Je ne sais pas comment accéder aux valeurs de chaîne dans un JSONArray. Par exemple, mon json ressemble à ceci:

{
  "locations": {
    "record": [
      {
        "id": 8817,
        "loc": "NEW YORK CITY"
      },
      {
        "id": 2873,
        "loc": "UNITED STATES"
      },
      {
        "id": 1501
        "loc": "NEW YORK STATE"
      }
    ]
  }
}

mon code:

JSONObject req = new JSONObject(join(loadStrings(data.json),""));
JSONObject locs = req.getJSONObject("locations");
JSONArray recs = locs.getJSONArray("record");

J'ai accès au JSONArray "record" à ce stade, mais je ne suis pas sûr de la façon dont j'obtiendrais les valeurs "id" et "loc" dans une boucle for. Désolé si cette description n'est pas trop claire, je suis un peu nouveau dans la programmation.

minimalpop
la source
2
Une autre chose (probablement vous l'avez trouvée) - vous avez manqué une virgule après la troisième valeur d'id. Il est bon de toujours utiliser un analyseur, par exemple json.parser.online.fr
Krystian

Réponses:

218

Avez-vous essayé d'utiliser JSONArray.getJSONObject (int) et JSONArray.length () pour créer votre boucle for:

for (int i = 0; i < recs.length(); ++i) {
    JSONObject rec = recs.getJSONObject(i);
    int id = rec.getInt("id");
    String loc = rec.getString("loc");
    // ...
}
notnoop
la source
Je ne comprends pas. Si nous pouvons obtenir idavec un sinple getIntcomme la façon dont nous obtenons la valeur d'un hashmap en spécifiant la clé, alors pourquoi devons-nous itérer avec une boucle for? L'itération avec la boucle n'entraîne-t-elle pas l' idattribution de int idplusieurs fois?
Nav
Pour JSON plus complexe, j'ai trouvé cette belle solution par examples.javacodegeeks.com/core-java/json
...
comment puis-je faire cela pour php?
Hanie Asemi
Comment cela fonctionnerait-il si je connais l'ID mais que j'ai besoin de la localisation correspondante?
ToofanHasArrivé
6

Un org.json.JSONArray n'est pas itérable.
Voici comment je traite les éléments dans un net.sf.json.JSONArray :

    JSONArray lineItems = jsonObject.getJSONArray("lineItems");
    for (Object o : lineItems) {
        JSONObject jsonLineItem = (JSONObject) o;
        String key = jsonLineItem.getString("key");
        String value = jsonLineItem.getString("value");
        ...
    }

Fonctionne très bien... :)

Piko
la source
10
Cela ne fonctionne pas pour moi, car a JSONArrayn'est pas itérable.
michel404
8
org.json.JSONArray n'est pas itérable, mais net.sf.json.JSONArray est Iterable
majgis
votre lien est rompu
VdeX
4

Java 8 est sur le marché après près de 2 décennies, voici le moyen d'itérer org.json.JSONArrayavec l'API java8 Stream.

import org.json.JSONArray;
import org.json.JSONObject;

@Test
public void access_org_JsonArray() {
    //Given: array
    JSONArray jsonArray = new JSONArray(Arrays.asList(new JSONObject(
                    new HashMap() {{
                        put("a", 100);
                        put("b", 200);
                    }}
            ),
            new JSONObject(
                    new HashMap() {{
                        put("a", 300);
                        put("b", 400);
                    }}
            )));

    //Then: convert to List<JSONObject>
    List<JSONObject> jsonItems = IntStream.range(0, jsonArray.length())
            .mapToObj(index -> (JSONObject) jsonArray.get(index))
            .collect(Collectors.toList());

    // you can access the array elements now
    jsonItems.forEach(arrayElement -> System.out.println(arrayElement.get("a")));
    // prints 100, 300
}

Si l'itération est une seule fois, (inutile de le faire .collect)

    IntStream.range(0, jsonArray.length())
            .mapToObj(index -> (JSONObject) jsonArray.get(index))
            .forEach(item -> {
               System.out.println(item);
            });
prier
la source
1
.mapToObjaffiche "exception non gérée: JSONException"
Andrejs
1
dans la syntaxe .mapToObj(index -> (JSONObject) array.get(index)), il y a jsonArray.get(index)ce qui peut potentiellement lancer, JSONExceptionmais JSONException extends RuntimeExceptioncela devrait donc bien au moins au moment de la compilation
prieragupd
2

En regardant votre code, je sens que vous utilisez JSONLIB. Si tel était le cas, regardez l'extrait de code suivant pour convertir le tableau json en tableau java.

 JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );  
 JsonConfig jsonConfig = new JsonConfig();  
 jsonConfig.setArrayMode( JsonConfig.MODE_OBJECT_ARRAY );  
 jsonConfig.setRootClass( Integer.TYPE );  
 int[] output = (int[]) JSONSerializer.toJava( jsonArray, jsonConfig );  
Teja Kantamneni
la source
0

Au cas où cela aiderait quelqu'un d'autre, j'ai pu convertir en un tableau en faisant quelque chose comme ça,

JSONObject jsonObject = (JSONObject)new JSONParser().parse(jsonString);
((JSONArray) jsonObject).toArray()

... ou vous devriez pouvoir obtenir la longueur

((JSONArray) myJsonArray).toArray().length
filaire00
la source
org.json.JSONObjecta une toJSONArray(JSONArray names)méthode et org.json.JSONArraya une toJSONObject(JSONArray names)méthode mais il n'a pas de toArray()méthode.
BrionS
-1

HashMap regs = (HashMap) parser.parse (stringjson);

(String) (( HashMap ) regs.get ("firstlevelkey")). Get ("secondlevelkey");

Roger
la source
1
Un peu plus de clarification pour savoir pourquoi votre réponse est meilleure que celle actuellement acceptée aiderait à comprendre votre solution.
Vadimo