TALJsonDocument is a Delphi parser/writer for JSON / BSON data format. it's support DOM and SAX parser, support BSON format (http://bsonspec.org/), and use a similar syntax than TALXMLDocument / TXMLDocument. TALJsonDocument can also export Json / Bson data in TALStringList.
When it deals with parsing some (textual) content, two directions are usually envisaged. In the JSON world, you have usually to make a choice between:
In fact, DOM parsers use internally a SAX parser to read the JSON content. Therefore, with the overhead of object creation and their property initialization, DOM parsers are typically three to five times slower than SAX (and use much much more memory to store all the nodes). But, DOM parsers are much more powerful for handling the data: as soon as it's mapped in native objects, code can access with no time to any given node, whereas a SAX-based access will have to read again the whole JSON content.
Most JSON parser available in Delphi use a DOM-like approach. For instance, the DBXJSON unit included since Delphi 2010 or the SuperObject library create a class instance mapping each JSON node. In order to achieve best speed, TALJsonDocument implement DOM parser and also a SAX parser.
TALJsonDocument syntax is very similar to TALXMLdocument / TXMLDocument
{ _id: 1, name: { first: "John", last: "Backus" }, birth: new Date('1999-10-21T21:04:54.234Z'), contribs: [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ], awards: [ { award: "National Medal of Science", year: 1975, by: "National Science Foundation" }, { award: "Turing Award", year: 1977, by: "ACM" } ], spouse: "", address: {}, phones: [] }
MyJsonDoc.loadFromJson(AJsonStr, False); MyJsonDoc.childnodes['_id'].int32; MyJsonDoc.childnodes['name'].childnodes['first'].text; MyJsonDoc.childnodes['name'].childnodes['last'].text; MyJsonDoc.childnodes['birth'].datetime; for i := 0 to MyJsonDoc.childnodes['contribs'].ChildNodes.count - 1 do MyJsonDoc.childnodes['contribs'].childnodes[i].text; for i := 0 to MyJsonDoc.childnodes['awards'].ChildNodes.count - 1 do begin MyJsonDoc.childnodes['awards'].childnodes[i].childnodes['award'].text; MyJsonDoc.childnodes['awards'].childnodes[i].childnodes['year'].text; MyJsonDoc.childnodes['awards'].childnodes[i].childnodes['by'].text; end;
MyJsonDoc.addchild('_id').int32 := 1; with MyJsonDoc.addchild('name', ntObject) do begin addchild('first').text := 'John'; addchild('last').text := 'Backus'; end; MyJsonDoc.addchild('birth').dateTime := Now; with MyJsonDoc.addchild('contribs', ntArray) do begin addchild.text := 'Fortran'; addchild.text := 'ALGOL'; addchild.text := 'Backus-Naur Form'; addchild.text := 'FP'; end; with MyJsonDoc.addchild('awards', ntArray) do begin with addchild(ntObject) do begin addchild('award').text := 'National Medal of Science'; addchild('year').int32 := 1975; addchild('by').text := 'National Science Foundation'; end; with addchild(ntObject) do begin addchild('award').text := 'Turing Award'; addchild('year').int32 := 1977; addchild('by').text := 'ACM'; end; end; MyJsonDoc.addchild('spouse'); MyJsonDoc.addchild('address', ntObject); MyJsonDoc.addchild('phones', ntArray);
MyJsonDoc.LoadFromFile(aBSONFileName, False{saxMode}, True{BSON}); MyJsonDoc.SaveToFile(aBSONFileName, False{saxMode}, True{BSON});
MyJsonDoc.onParseText := procedure (Sender: TObject; const Path: AnsiString; const name: AnsiString; const str: AnsiString; const NodeSubType: TALJSONNodeSubType) begin Writeln(Path + '=' + str); end; MyJsonDoc.LoadFromJSON(AJsonStr, true{saxMode});