Frage zur Extraktion von JSON Daten unterschiedl. Aufbaus

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Frage zur Extraktion von JSON Daten unterschiedl. Aufbaus

Beitrag von Kurzer »

Moin zusammen,

ich bin offenbar nicht der JSON Typ - jedenfalls kämpfe ich gerade mit einer sehr einfachen JSON-Struktur, die ich nicht extrahiert bekomme.
Und zwar möchte ich einen JSON String der immer gleiche Kopfelemente, aber unterschiedliche "Detaileinträgen" hat, in eine immer gleich aufgebaute Struktur extrahieren.

Der String hat dabei folgenden Aufbau (hier direkt als reales Beispiel):

Code: Alles auswählen

{"status":"OK",
  "message":"Der Benutzer wurde angemeldet.",
  "count":1,
  "datablock": 
     [
      {"users_id":"2",
        "accesslevel":"1",
        "firstname":"test2",
        "lastname":"test2",
        "alias":"TE2",
        "email":"test2@test.de",
        "active":"1"
       }
     ]
}
Datablock kann dabei entweder nichts enthalten ("datablock":[]) oder ein oder mehrere Objekte mit unterschiedlichem Aufbau. Mit "unterschiedlich" ist gemeint, dass der Aufbau innerhalb eines JSON-Strings gleich ist, es aber unterschiedliche JSON-String Typen gibt, die alle in die selbe Struktur extrahiert werden sollen. Wenn also z.B. Userdaten kommen (siehe Beispiel oben), dann sind die Values in datablock[] anders benannt als bei Produkten - siehe folgendes Beispiel:

Code: Alles auswählen

"datablock":
[
  {"product_id":"1008",
    "name":"Erbsensuppe",
    "price":"0,89",
    "stockamount":"29"
  },
  {"product_id":"1009",
   "name":"Brathering",
   "price":"2,19",
   "stockamount":"31"
  }
]
Mein Gedanke war nun, dass ich für die Array-Aufzählung in "datablock":[{...}] eine Liste nehme, die ihrerseits wieder Maps für die JSON Objekte enthalten "datablock":[{...}] .
Leider funktioniert das nicht so wie ich mir das vorstelle. Muss ich hier mit Pointern arbeiten oder wie realisiert man das?

Code: Alles auswählen

EnableExplicit
	
Structure structDataBlock
	Map datablockmember.s()
EndStructure

Structure structResponse
	status.s
	message.s
	count.i
	List datablock.structDataBlock()
EndStructure

Global stResponse.structResponse
Global sResult.s

;sResult = ~"{\"status\":\"OK\",\"message\":\"Der Benutzer wurde erfolgreich abgemeldet.\",\"count\":0,\"datablock\":[]}"
sResult = ~"{\"status\":\"OK\",\"message\":\"Der Benutzer wurde angemeldet.\",\"count\":1,\"datablock\":[{\"users_id\":\"2\",\"accesslevel\":\"1\",\"firstname\":\"test2\",\"lastname\":\"test2\",\"alias\":\"TE2\",\"email\":\"test2@test.de\",\"active\":\"1\"}]}"
;sResult = ~"{\"status\":\"OK\",\"message\":\"Produktinformationen\",\"count\":1,\"datablock\":[{\"product_id\":\"1008\",\"name\":\"Erbsensuppe\",\"price\":\"0,89\",\"stockamount\":\"29\"}]}"
;sResult = ~"{\"status\":\"OK\",\"message\":\"Produktinformationen\",\"count\":2,\"datablock\":[{\"product_id\":\"1008\",\"name\":\"Erbsensuppe\",\"price\":\"0,89\",\"stockamount\":\"29\"},{\"product_id\":\"1009\",\"name\":\"Brathering\",\"price\":\"2,19\",\"stockamount\":\"31\"}]}"

Debug sResult
If ParseJSON(0, sResult)
	ExtractJSONStructure(JSONValue(0), @stResponse, structResponse)
	FreeJSON(0)
	Debug stResponse\status + ": " + stResponse\message + ", Count: " + stResponse\count
	
	ForEach stResponse\datablock()
		ForEach  stResponse\datablock()\datablockmember()
			Debug stResponse\datablock()\datablockmember()
		Next
	Next
	
Else
	Debug "JSON Fehler"
EndIf
Gruß Markus
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Frage zur Extraktion von JSON Daten unterschiedl. Aufbau

Beitrag von Kurzer »

Wenn ich es "zu Fuß" extrahiere, dann funktioniert es.

Ist mein Beispiel für ExtractJSONStructure zu komplex? Sollte ExtractJSONStructure damit umgehen können und es ist ein Bug oder gibt es andere Gründe, warum es nicht mittels ExtractJSONStructure extrahiert werden kann?

Markus

Code: Alles auswählen

EnableExplicit

Structure structResultRow
	Map ResultRow.s()
EndStructure

Structure structResultSet
	status.s
	message.s
	count.i
	List ResultSet.structResultRow()
EndStructure

Global stResult.structResultSet
Global.s sResult, ItemKey, ItemValue
Global.i iResultObject, iResultSet, iResultRow, iRowCount, iMaxRows

;sResult = ~"{\"status\":\"OK\",\"message\":\"Der Benutzer wurde erfolgreich abgemeldet.\",\"count\":0,\"datablock\":[]}"
;sResult = ~"{\"status\":\"OK\",\"message\":\"Der Benutzer wurde angemeldet.\",\"count\":1,\"datablock\":[{\"users_id\":\"2\",\"accesslevel\":\"1\",\"firstname\":\"test2\",\"lastname\":\"test2\",\"alias\":\"TE2\",\"email\":\"test2@test.de\",\"active\":\"1\"}]}"
;sResult = ~"{\"status\":\"OK\",\"message\":\"Produktinformationen\",\"count\":1,\"datablock\":[{\"product_id\":\"1008\",\"name\":\"Erbsensuppe\",\"price\":\"0,89\",\"stockamount\":\"29\"}]}"
sResult = ~"{\"status\":\"OK\",\"message\":\"Produktinformationen\",\"count\":2,\"datablock\":[{\"product_id\":\"1008\",\"name\":\"Erbsensuppe\",\"price\":\"0,89\",\"stockamount\":\"29\"},{\"product_id\":\"1009\",\"name\":\"Brathering\",\"price\":\"2,19\",\"stockamount\":\"31\"}]}"

Debug sResult
If ParseJSON(0, sResult)
	;ClearStructure(@stResponse, structResultSet)
	
	ExtractJSONStructure(JSONValue(0), @stResult, structResultSet)
	iResultObject =JSONValue(0)
	
	If ExamineJSONMembers(iResultObject)
		While NextJSONMember(iResultObject)
			If JSONMemberKey(iResultObject) = "datablock"
				iResultSet = JSONMemberValue(iResultObject) ; JSON Array
				Break
			EndIf
		Wend
	EndIf
	
	iMaxRows = JSONArraySize(iResultSet) - 1
	For iRowCount = 0 To iMaxRows
		AddElement(stResult\ResultSet())
		iResultRow = GetJSONElement(iResultSet, iRowCount) ; JSON Object
		If ExamineJSONMembers(iResultRow)
			While NextJSONMember(iResultRow)
				ItemKey = JSONMemberKey(iResultRow)
				ItemValue = GetJSONString(JSONMemberValue(iResultRow))
				stResult\ResultSet()\ResultRow(ItemKey) = ItemValue
			Wend
		EndIf
	Next iRowCount
	
	FreeJSON(0)
	
	; Ausgabe
	Debug "Status: " + stResult\status
	Debug "Message: " + stResult\message
	Debug "Datablock entries: " + stResult\count
	ForEach stResult\ResultSet()
		ForEach stResult\ResultSet()\ResultRow()
			Debug MapKey(stResult\ResultSet()\ResultRow()) + ": " + stResult\ResultSet()\ResultRow()
		Next
	Next
Else
	Debug "JSON Fehler"
EndIf
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: Frage zur Extraktion von JSON Daten unterschiedl. Aufbau

Beitrag von Sicro »

Das veranschaulicht dir, wo das Problem liegt:

Code: Alles auswählen

Structure structDataBlock
  Map datablockmember.s()
EndStructure

Structure structResponse
  status.s
  message.s
  count.i
  List datablock.structDataBlock()
EndStructure

Global stResponse.structResponse

With stResponse
  \status = "OK"
  \message = "Der Benutzer wurde angemeldet."
  \count = 1
  AddElement(\datablock())
  \datablock()\datablockmember("user_id") = "2"
  \datablock()\datablockmember("accesslevel") = "1"
EndWith

If CreateJSON(0)
  InsertJSONStructure(JSONValue(0), @stResponse, structResponse)
  Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
EndIf
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Frage zur Extraktion von JSON Daten unterschiedl. Aufbau

Beitrag von Kurzer »

Hallo Sicro,

danke für den Hinweis sich das ganze mal aus einem andere Blickwinkel anzusehen (quasi von der anderen Seite).
Manche Sachen sind so einfach, dass man nicht drauf kommt. Und trotzdem sind sie so effektiv. :allright:

Ich habe die Aufbereitung des datablocks in meinem PHP Modul entsprechend angepasst und jetzt funktioniert die Dekodierung auch mit Extract JSONStructure().

Code: Alles auswählen

// $data ist das Array mit den Resultzeilen
      $items = [];
      foreach($data as $value)
      {
        $items[] = array('datablockmember' => $value);
      }
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Antworten