java - recorrer - ¿Cómo iterar sobre un objeto JSON?
pasar un objeto a json java (11)
Uso una biblioteca JSON llamada JSONObject
(no me importa cambiar si necesito hacerlo).
Sé cómo iterar sobre JSONArrays
, pero cuando JSONArrays
datos JSON de Facebook no obtengo una matriz, solo un objeto JSONObject
, pero necesito poder acceder a un elemento a través de su índice, como JSONObject[0]
para obtener La primera, y no sé cómo hacerlo.
{
"http://http://url.com/": {
"id": "http://http://url.com//"
},
"http://url2.co/": {
"id": "http://url2.com//",
"shares": 16
}
,
"http://url3.com/": {
"id": "http://url3.com//",
"shares": 16
}
}
A continuación el código funcionó bien para mí. Por favor, ayúdame si se puede hacer la afinación. Esto obtiene todas las claves incluso de los objetos JSON anidados.
public static void main(String args[]) {
String s = ""; // Sample JSON to be parsed
JSONParser parser = new JSONParser();
JSONObject obj = null;
try {
obj = (JSONObject) parser.parse(s);
@SuppressWarnings("unchecked")
List<String> parameterKeys = new ArrayList<String>(obj.keySet());
List<String> result = null;
List<String> keys = new ArrayList<>();
for (String str : parameterKeys) {
keys.add(str);
result = this.addNestedKeys(obj, keys, str);
}
System.out.println(result.toString());
} catch (ParseException e) {
e.printStackTrace();
}
}
public static List<String> addNestedKeys(JSONObject obj, List<String> keys, String key) {
if (isNestedJsonAnArray(obj.get(key))) {
JSONArray array = (JSONArray) obj.get(key);
for (int i = 0; i < array.length(); i++) {
try {
JSONObject arrayObj = (JSONObject) array.get(i);
List<String> list = new ArrayList<>(arrayObj.keySet());
for (String s : list) {
putNestedKeysToList(keys, key, s);
addNestedKeys(arrayObj, keys, s);
}
} catch (JSONException e) {
LOG.error("", e);
}
}
} else if (isNestedJsonAnObject(obj.get(key))) {
JSONObject arrayObj = (JSONObject) obj.get(key);
List<String> nestedKeys = new ArrayList<>(arrayObj.keySet());
for (String s : nestedKeys) {
putNestedKeysToList(keys, key, s);
addNestedKeys(arrayObj, keys, s);
}
}
return keys;
}
private static void putNestedKeysToList(List<String> keys, String key, String s) {
if (!keys.contains(key + Constants.JSON_KEY_SPLITTER + s)) {
keys.add(key + Constants.JSON_KEY_SPLITTER + s);
}
}
private static boolean isNestedJsonAnObject(Object object) {
boolean bool = false;
if (object instanceof JSONObject) {
bool = true;
}
return bool;
}
private static boolean isNestedJsonAnArray(Object object) {
boolean bool = false;
if (object instanceof JSONArray) {
bool = true;
}
return bool;
}
Con Java 8 y lambda, limpiador:
JSONObject jObject = new JSONObject(contents.trim());
jObject.keys().forEachRemaining(k ->
{
});
En mi caso, encontré iterar los names()
funciona bien.
for(int i = 0; i<jobject.names().length(); i++){
Log.v(TAG, "key = " + jobject.names().getString(i) + " value = " + jobject.get(jobject.names().getString(i)));
}
Evitaré el iterador ya que pueden agregar / eliminar objetos durante la iteración y también para el uso de código limpio en un bucle for. menos línea de código simple.
import org.json.simple.JSONObject;
public static void printJsonObject(JSONObject jsonObj) {
for (Object key : jsonObj.keySet()) {
//based on you key types
String keyStr = (String)key;
Object keyvalue = jsonObj.get(keyStr);
//Print key and value
System.out.println("key: "+ keyStr + " value: " + keyvalue);
//for nested objects iteration if required
if (keyvalue instanceof JSONObject)
printJsonObject((JSONObject)keyvalue);
}
}
Hice una pequeña función recursiva que recorre todo el objeto json y guarda la ruta de la clave y su valor.
// My stored keys and values from the json object
HashMap<String,String> myKeyValues = new HashMap<String,String>();
// Used for constructing the path to the key in the json object
Stack<String> key_path = new Stack<String>();
// Recursive function that goes through a json object and stores
// its key and values in the hashmap
private void loadJson(JSONObject json){
Iterator<?> json_keys = json.keys();
while( json_keys.hasNext() ){
String json_key = (String)json_keys.next();
try{
key_path.push(json_key);
loadJson(json.getJSONObject(json_key));
}catch (JSONException e){
// Build the path to the key
String key = "";
for(String sub_key: key_path){
key += sub_key+".";
}
key = key.substring(0,key.length()-1);
System.out.println(key+": "+json.getString(json_key));
key_path.pop();
myKeyValues.put(key, json.getString(json_key));
}
}
if(key_path.size() > 0){
key_path.pop();
}
}
No crea que no hay una solución más simple y segura que usar un iterador ...
El método JSONObject names ()
devuelve un JSONArray de las claves JSONObject, por lo que simplemente puede caminar en bucle:
JSONObject object = new JSONObject ();
JSONArray keys = object.names ();
for (int i = 0; i < keys.length (); ++i) {
String key = keys.getString (i); // Here''s your key
String value = object.getString (key); // Here''s your value
}
Primero pon esto en alguna parte:
private <T> Iterable<T> iteratorToIterable(final Iterator<T> iterator) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return iterator;
}
};
}
O si tienes acceso a Java8, solo esto:
private <T> Iterable<T> iteratorToIterable(Iterator<T> iterator) {
return () -> iterator;
}
Luego simplemente itere sobre las claves y valores del objeto:
for (String key : iteratorToIterable(object.keys())) {
JSONObject entry = object.getJSONObject(key);
// ...
Tal vez esto ayude:
jsonObject = new JSONObject(contents.trim());
Iterator<String> keys = jsonObject.keys();
while(keys.hasNext()) {
String key = keys.next();
if (jObject.get(key) instanceof JSONObject) {
}
}
Una vez tuve un json que tenía ids que necesitaban ser incrementados en uno ya que tenían un índice de 0 y eso estaba rompiendo el auto-incremento de Mysql.
Entonces, para cada objeto que escribí este código, podría ser útil para alguien:
public static void incrementValue(JSONObject obj, List<String> keysToIncrementValue) {
Set<String> keys = obj.keySet();
for (String key : keys) {
Object ob = obj.get(key);
if (keysToIncrementValue.contains(key)) {
obj.put(key, (Integer)obj.get(key) + 1);
}
if (ob instanceof JSONObject) {
incrementValue((JSONObject) ob, keysToIncrementValue);
}
else if (ob instanceof JSONArray) {
JSONArray arr = (JSONArray) ob;
for (int i=0; i < arr.length(); i++) {
Object arrObj = arr.get(0);
if (arrObj instanceof JSONObject) {
incrementValue((JSONObject) arrObj, keysToIncrementValue);
}
}
}
}
}
uso:
JSONObject object = ....
incrementValue(object, Arrays.asList("id", "product_id", "category_id", "customer_id"));
esto también se puede transformar para que funcione para JSONArray como objeto principal
org.json.JSONObject ahora tiene un método keySet () que devuelve un Set<String>
y se puede enlazar fácilmente con un para cada uno.
for(String key : jsonObject.keySet())
Iterator<JSONObject> iterator = jsonObject.values().iterator();
while (iterator.hasNext()) {
jsonChildObject = iterator.next();
// Do whatever you want with jsonChildObject
String id = (String) jsonChildObject.get("id");
}