Sto cercando di analizzare alcuni JSON restituiti da un servizio Web REST. Il ritorno dalla chiamata get() è un TStringStream. Sto usando dbxjson per lavorare con i dati. Per rendere le cose più facili da dimostrare qui, ho creato un progetto di test che riproduce l'errore senza chiamare il servizio Web (utilizza invece un file di testo per l'output del servizio Web). Ecco il codice:JSON empty array
var SL : TStringStream;
LJsonObj : TJSONObject;
begin
SL := TStringStream.Create;
try
SL.LoadFromFile('output.txt');
LJsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(SL.DataString), 0) as TJSONObject;
finally
SL.Free;
end;
end;
A volte l'array phone_numbers in questo dato JSON è vuoto. Nell'oggetto flusso proveniente dalla chiamata di servizio web, sembra che questo:
{
"Contact Information Service": {
"response": {
"phone_numbers": [
]
}
}
}
Questo fa sì che ParseJSONValue per restituire un valore pari a zero.
Tuttavia, se cambio la numeri_di_telefono array vuoto a questo nel mio test file txt:
{
"Contact Information Service": {
"response": {
"phone_numbers": []
}
}
}
funziona bene (cioè restituisce un TJSONObject). La differenza è lo spazio bianco nell'array vuoto. Per qualche motivo, la prima risposta JSON con spazi bianchi nell'array vuoto fa sì che ParseJSONValue restituisca zero. Funziona bene senza spazi bianchi tra le parentesi quadre.
Cosa sto facendo male con il mio parsing JSON? C'è una sorta di pre-analisi che devo fare prima di chiamare ParseJSONValue?
Sembra che molto probabilmente si tratta di un bug nell'implementazione di TJSONByteReader, ma sinceramente il tentativo di dare un senso al codice di analisi rende impossibile dirlo a colpo d'occhio. Empiricamente le prove sono abbastanza chiare. Fortunatamente il mio lettore TJSONObject gestisce perfettamente questi casi. Tempo di pubblicare forse? :) – Deltics
@Deltics: Davvero? L'ho tracciato mentre indagavo su questa domanda, e non ho trovato così difficile capire il codice di analisi.Penso che il parser sia scritto male - questo problema sarebbe stato evitato completamente se avesse un lexer adatto invece di mescolare il lexing con l'analisi - ma non è troppo difficile capire cosa sta succedendo ... –
Se hai trovato PeekByte() facile da capire, allora devi sognare in esadecimale. :) Quando pubblico il mio codice JSON vedrai la differenza tra il codice che considero leggibile (oserei dire manutenibile) e, um, dbxJSON. – Deltics