Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » Elevate Web Builder Technical Support » Support Forums » Elevate Web Builder General » View Thread |
Messages 1 to 10 of 14 total |
TReader parsing problem with nested arrays |
Thu, Mar 22 2018 4:55 AM | Permanent Link |
Uli Becker | Hi,
Not easy to read, sorry. Maybe something for Tim. I am using TReader to parse JSON (persistent fields). Attached some screenshots (better than posting unformatted text) to make clear what's my problem: Clip1: "state": I use MyReader.LoadObject and pull out what I need (I don't need the values from the array "XY"). No problem. Clip2: "capabilities": I don't need this at all (at the moment), but here TReader throws an exception (Clip3). Obviously the nested arrays "colorgamut" cause the problem. Two questions: 1. How can I skip the whole object "capabilities"? 2. If I need the values from "colorgamut": how do I parse an array of arrays? Thanks Uli Attachments: Clip1.png Clip2.png Clip3.png |
Thu, Mar 22 2018 5:15 AM | Permanent Link |
Matthew Jones | First step, I'd create matching objects, and a simple project that has a fixed string. Then you can experiment a lot more easily. (Maybe you have already done this, worth posting for people to play with perhaps.)
You don't show any code, so hard to comment further. Do you have a function in your object like this: function TMyObject.LoadProperty(AReader: TReader): Boolean; var szPropertyName : String; begin Result := False; szPropertyName := AReader.GetPropertyName; if (szPropertyName <> '') then begin if SameText(szPropertyName, 'myarray') then begin Result := True; AReader.SkipPropertyName; AReader.SkipPropertySeparator; LoadArray(AReader); end else begin Result := inherited LoadProperty(AReader); end; end; end; That's the basic way to be reading properties that are other objects and arrays. I found that it was handy to run through the code in the Chrome debugger too, as you can see what is happening, or add other debugging "printf"s. -- Matthew Jones |
Thu, Mar 22 2018 9:05 AM | Permanent Link |
Uli Becker | Matthew,
> First step, I'd create matching objects, and a simple project that has a fixed string. Then you can experiment a lot more easily. (Maybe you have already done this, worth posting for people to play with perhaps.) Yes, I did then when writing the code for this app. Ran fine until the incoming JSON was changed from a simple array to an array of arrays like I showed. > Do you have a function in your object like this: Generally yes, sure. But in this case I don't need the values of the array, so I've no code for it. In the "state" object there is also an array "xy", which I don't need (and don't parse). No problem for TReader. The question is how to deal with the "colorgamut" array (or how to skip it). Thanks Uli |
Thu, Mar 22 2018 9:50 AM | Permanent Link |
Matthew Jones | Uli Becker wrote:
> I don't need the values of the array, so I've no code for it. I think you are going to have to write the code for it, skipping the objects until it gets back to where you started. I had code for the old parser to do this, and maybe there is code in the library that shows how to skip hierarchically. Recursion may follow! 8-) -- Matthew Jones |
Thu, Mar 22 2018 11:23 AM | Permanent Link |
Raul Team Elevate | On 3/22/2018 4:55 AM, Uli Becker wrote:
> Two questions: > 1. How can I skip the whole object "capabilities"? > 2. If I need the values from "colorgamut": how do I parse an array of > arrays? Could you post a sample json ? (i did not see one) I find this type of thing a lot easier to look at with a sample. Raul |
Thu, Mar 22 2018 1:49 PM | Permanent Link |
Uli Becker | Raul,
> Could you post a sample json ? (i did not see one) > > I find this type of thing a lot easier to look at with a sample. Sure, I posted screenshot of formatted json to make it more readable, but here a part of the json I'm trying to parse: "1": { "state": { "on": true, "bri": 142, "hue": 2905, "sat": 115, "effect": "none", "xy": [ 0.4945, 0.3659 ], "ct": 432, "alert": "none", "colormode": "xy", "mode": "homeautomation", "reachable": true }, "swupdate": { "state": "noupdates", "lastinstall": "2017-12-22T15:59:36" }, "type": "Extended color light", "name": "Vitrine", "modelid": "LCT015", "manufacturername": "Philips", "productname": "Hue color lamp", "capabilities": { "certified": true, "control": { "mindimlevel": 1000, "maxlumen": 806, "colorgamuttype": "C", "colorgamut": [ [ 0.6915, 0.3083 ], [ 0.17, 0.7 ], [ 0.1532, 0.0475 ] ], "ct": { "min": 153, "max": 500 } }, "streaming": { "renderer": true, "proxy": true } }, "config": { "archetype": "sultanbulb", "function": "mixed", "direction": "omnidirectional" }, "uniqueid": "00:17:88:01:03:6f:9d:57-0b", "swversion": "1.29.0_r21169", "swconfigid": "3416C2DD", "productid": "Philips-LCT015-1-A19ECLv5" } Thanks Uli |
Fri, Mar 23 2018 6:33 AM | Permanent Link |
Uli Becker | Meanwhile I found a solution (maybe not the best, but it works):
Since the "inner" array has no PropertyName, I set a variable to identify the array, then parse this array like this: function TLight.LoadProperty(AReader: TReader): Boolean; var TempName: String; begin Result := False; TempName := AReader.GetPropertyName; CurrentPropertyName := TempName; if SameText(TempName,'state') then begin ... end else if SameText(TempName,'Capabilities') then begin ... end else if SameText(TempName,'Control') then begin ... end else if SameText(TempName,'ColorGamut') then begin Result := True; AReader.SkipPropertyName; AReader.SkipPropertySeparator; LoadArray(AReader); end else if SameText(TempName,'ColorGamutInner') then begin Result := True; LoadArray(AReader); end else inherited LoadProperty(AReader); end; function TLight.LoadArrayElement(AReader: TReader): Boolean; begin if SameText(CurrentPropertyName,'ColorGamut') then begin CurrentPropertyName := 'ColorGamutInner'; AReader.ReadString; // no need to read the values, just to continue result := true; end else if SameText(CurrentPropertyName,'ColorGamutInner') then begin AReader.ReadString; // no need to read the values, just to continue result := true; end else result := inherited LoadArrayElement(AReader); end; Thanks to all. Uli |
Sat, Mar 24 2018 6:29 AM | Permanent Link |
Walter Matte Tactical Business Corporation | Uli Becker wrote:
<<Meanwhile I found a solution (maybe not the best, but it works):>> I posted a JSON Parser unit in EWB components (with a test program with your sample JSON) - mine may not be the best parser - but it works. https://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb_components&page=1&msg=152#152 Walter |
Sat, Mar 24 2018 6:57 AM | Permanent Link |
Uli Becker | Hi Walter,
> I posted a JSON Parser unit in EWB components (with a test program with your sample JSON) - mine may not be the best parser - but it works. Thanks a lot for that - much appreciated. It works even with unformatted JSON, takes about 10 seconds though. Since incoming JSON is never formatted, that will be a problem. Have to look into the sources. Great work anyway. Uli |
Sat, Mar 24 2018 8:24 AM | Permanent Link |
Walter Matte Tactical Business Corporation | Uli
Formatted or unformated - does not matter is parses character by character.... size of json string parsed will therefore affect speed. ... I didn't play with larger samples... I will for fun. Walter |
Page 1 of 2 | Next Page » | |
Jump to Page: 1 2 |
This web page was last updated on Wednesday, October 9, 2024 at 05:37 AM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |