NEWS
JSON interpretieren
-
@150d Ja tuts ja - Nenn mal Deine Variable nicht json sondern str oder irgendwas. - Du siehst doch dass ich mit Deinem JSON string kein Problem habe. Der String muss in "Hochkommas"
-
@150d sagte: warum
data = JSON.parse(json);
nicht funktioniert.Ist das vermeintliche JSON vielleicht kein JSON, sondern bereits ein Objekt?
-
@paul53 sagte in JSON interpretieren:
@150d sagte: warum
data = JSON.parse(json);
nicht funktioniert.Ist das vermeintliche JSON vielleicht kein JSON, sondern bereits ein Objekt?
Ja das kann SEIN, weil sonst würde er es oben ja nicht stringifizieren.
-
In der Tat, das funktioniert. (Ich bin neu hier - bei JavaScript -; ich weiß noch nicht so genau, was ich tue...
)
Was ich möchte:
Der JSON-String soll rekursiv geparst werden und aus dem Inhalt ioBroker-States angelegt werden. Folgendes habe ich versucht:
function parse_json_data(jsondata) { for (var substr in jsondata) { if (typeof substr === "object") { return parse_json_data(substr); } else { adapter.log.info("substring: " + substr); } } }
Das klappt aber nicht, es wird nur der eine Eintrag "overview" erkannt. Die Rekursion funktioniert nicht.
Wie kann ich zwischen "Knoten" und "Blatt" unterscheiden?
-
gelöscht - du hast ja for in genutzt, aber substr ist der Key und nicht das Objekt.
-
(delete - checking...
)
-
if (typeof jsondata[substr] === "object"){ return parse_json_data(jsondata[substr] ); }
In substr ist der key - als der Eigenschaftsname des Wertes innerhalb des Objektes. Wenn die Eigenschaft wieder auf Objekt abprüfst, musst Du das über das Objekt referenzieren.
-
@150d sagte: Der JSON-String soll rekursiv geparst werden und aus dem Inhalt ioBroker-States angelegt werden.
Das macht man nicht mit dem JSON, sondern mit dem Objekt. Beispiel:
const path = '0_userdata.0.inverter'; const myobj = {"overview":{"lastUpdateTime":"2023-07-21 17:03:35","lifeTimeData":{"energy":860933},"lastYearData":{"energy":319056},"lastMonthData":{"energy":319056},"lastDayData":{"energy":24741},"currentPower":{"power":2135},"measuredBy":"INVERTER"}}; function iter(id, obj) { for(let prop in obj) { if(typeof obj[prop] == 'object') iter(id + '.' + prop, obj[prop]); else { let idDp = id + '.' + prop; log(idDp + ': ' + obj[prop]); // if(existsState(idDp)) setState(idDp, obj[prop]); // else createState(idDp, obj[prop]); } } } iter(path, myobj);
-
du kannst das mal probieren
function iterate(obj, stack) { for (var property in obj) { if (obj.hasOwnProperty(property)) { if (typeof obj[property] == "object") { iterate(obj[property], stack + '.' + property); } else { console.log(property + " " + obj[property]); } } } } iterate(object, '')
ich sehe ich gerade, das die stackvariable irgendwie nirgends zugewiesen wird, eigentlich sollte die dafür da sein, um den propertypfad mit auszugeben.
Nachtrag, das war Paul schneller
Evtl musst du auch noch Sonderbehandlung für Array und den anderen primitivtypen einbauen -
Ok, bin weitergekommen. Die Rekursion funktioniert jetzt "nach unten", aber sie "kommt nicht wieder hoch":
Nochmal zur Erinnerung das JSON, "prettified":
{ "overview":{ "lastUpdateTime":"2023-07-21 18:41:46", "lifeTimeData":{ "energy":863588 }, "lastYearData":{ "energy":321711 }, "lastMonthData":{ "energy":321711 }, "lastDayData":{ "energy":27396 }, "currentPower":{ "power":1152 }, "measuredBy":"INVERTER" } }
Und hier der Code, den ich bis jetzt habe:
function parse_json_data(jsondata, prefix) { for (var substr in jsondata) { if (typeof jsondata[substr] === "object") { // found object, do recursion: return parse_json_data(jsondata[substr], prefix + substr + "."); } else { // not an object, print key/value pair: adapter.log.info("JSON key/value: " + prefix + substr + " = " + jsondata[substr]); } } }
Dies produziert folgende Ausgabe:
JSON key/value: overview.lastUpdateTime = 2023-07-21 18:41:46 JSON key/value: overview.lifeTimeData.energy = 863588
... es wird also:
- das erste Objekt identifiziert (overview),
- darin ein key/value gefunden (lastUpdateTime),
- dann wieder ein Objekt (lifeTimeData),
- darin ein key/value (energy).
Aber dann ist Schluss, weitere Behandlung findet nicht mehr statt.
Warum geht die for-Schleife nicht zum nächsten item (lastYearData) weiter?
-
@150d
Bei meinem Vorschlag kommt das im Log:19:08:57.895 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.lastUpdateTime: 2023-07-21 17:03:35 19:08:57.895 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.lifeTimeData.energy: 860933 19:08:57.895 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.lastYearData.energy: 319056 19:08:57.895 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.lastMonthData.energy: 319056 19:08:57.895 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.lastDayData.energy: 24741 19:08:57.895 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.currentPower.power: 2135 19:08:57.896 info javascript.1 (2174) script.js.common.ObjectStruct2ID: 0_userdata.0.inverter.overview.measuredBy: INVERTER
Das return in Zeile 9 verhindert die weitere Iteration.
-
@paul53 said in JSON interpretieren:
Das return in Zeile 9 verhindert die weitere Iteration.
Jawohl, das war es. (Dieses JavaScript ist vielleicht krümelkackerisch...
)
Danke!
Und danke an alle beteiligten!