The "automatic-fallback-mode to Decimal" I was suggesting (when Integer-Numbers get too large) would hurt nobody
(even in the Default-Setting "Parse-Numbers-into-Doubles") and would require the least efforts, when dile does it himself.
But as said, it was only a well-meant suggestion (take it or leave it)...
Olaf
I'm not arguing with you - It's definitely a good suggestion.
You're repeating yourself.
My point was, that this property would be completely unnecessary (with just a slight addition in your parsing-code).
As it is, it is just confusing - especially since it behaves inconsistently (and is *not* adhering to your "documentation").
Since you say in your Doc: "...this property determines how numbers are parsed and serialized..."
Example:
Code:
Dim JB1 As New JsonBag
JB1.DecimalMode = False '<- use Double-Mode
JB1.JSON = "{""longNumber"":1556427511093526531}"
Debug.Print JB1("longNumber") 'will print 1.55642751109353E+18
Dim JB2 As New JsonBag
JB2.DecimalMode = False '<- use Double-Mode
JB2("longNumber") = CDec("1556427511093526531")
Debug.Print JB2.JSON 'will print {"longNumber":1556427511093526531}
So - the latter result (of JB2 above) is not holding its promise (to serialize in Double-Format, as the Doc states),
since a Double clearly cannot hold an integer-value in that precision (as the first printout of JB1 shows).
So, as already suggested - either fix your code - or your wrong documentation
(now curious whether you're able to manage one of the two things without further sidekicks,
a simple "dear fellow-developer, thank you for pointing that out" would already be enough... <g>).
This property setting only impacts assignments to the JSON property, i.e. parsing serialized JSON. If you directly assign a numeric value the actual type your code used is stored in the object hierarchy data. Of course as noted it may also impact retrieval from the JSON property, i.e. serializing the tree into JSON text.
The behavior you showed above matches this exactly. If anything perhaps there is a small flaw there (the bold text you quoted), but unlike some people I provide both the source and documentation. I'll keep this documentation change in mind for a future release. At least it has been covered to death here now though.
Last edited by dilettante; Jan 22nd, 2017 at 12:36 AM.
An obscure body in the SK system. The inhabitants call it Earth
Posts
7,932
Re: VB6 - JsonBag, Another JSON Parser/Generator
Let's cut back on the sniping shall we... in both directions. You've both provided some excellent work in this forum and both deserve to have that acknowledged.
keep any criticism friendly and constructive and let's receive it in the same vein.
Last edited by FunkyDexter; Jan 22nd, 2017 at 05:25 AM.
The best argument against democracy is a five minute conversation with the average voter - Winston Churchill
Hadoop actually sounds more like the way they greet each other in Yorkshire - Inferrd
Hey guys,
i' on was on the version 1,6, it was working perfectly, thanks for great job.
But One week ago our IT updatet the Office 2010 to 64 bit and it didn't work
Ok, i updatet the JsonBag to version 2,5 and now i have the problem with "Names"
"Set ContractNames = JsRoot.Item(x1).Item("rows").Item(x2).Item("data").Names"
unfortunately after set the object is always ContractNames = nothing
Can you help me please?
json is attached
Hey guys!
our it updated the office to the 64 bit version, so i updated jsonbag to the 2.5 version and now i have a problem with the "names"
Set ContractNames = JsRoot.Item(x1).Item("rows").Item(x2).Item("data").Names
after set is the object ContractNames = nothing
can you tell me, what i am doing wrong? thanks in advance
PS: json is attached
PSS: sorry for my bad english
Hey guys!
our it updated the office to the 64 bit version, so i updated jsonbag to the 2.5 version and now i have a problem with the "names"
Set ContractNames = JsRoot.Item(x1).Item("rows").Item(x2).Item("data").Names
after set is the object ContractNames = nothing
can you tell me, what i am doing wrong? thanks in advance
PS: json is attached
PSS: sorry for my bad english
They are gone because they're supposed to be gone. That isn't from the parser but the serializer.
JSON has just a simple "number" type for numeric values. On decoding these become Double (or optionally Decimal). Don't be confused about the text representation once re-encoded back to JSON. JSONBag serializes numeric values back to a compact form, desirable to keep transmission costs down.
Nothing in the JSON spec requires retaining the original formatting of a value within the parsed JSON text. Even if it did, there are no rules to tell you how to format the value if changed or a new value is added, etc. JSON makes no provision for formatting numeric values any particular way as long as they result in a legal JSON "number."
If you really, really wanted this for some odd reason you would have to add another property to each numeric JSONBag item for "format" though I have no idea how reliable the parser could be at deciding what "format string" to assign when values are parsed.
Happy New Year. Decided to come off my break early so in response to your questions:
If you break execution in the IDE what line is it on?
Running your Demo2 from Version 2.5, with my bookmarks.json file.
Everytime I break it end up in Form1:Proc: "DumpText"
At break bookmarks.json values are valid as I search bookmarks file to verify.
Just seems to repeat -- stuck in loop.
Can you provide sample data that reproduces the problem?
This is a tough one as using a copy of my actual bookmarks file.
See what I can do.
... the parsing is done. So the problem is probably not in JsonBag at all.
The rest of that program (mainly JbDump) just tries to walk the JsonBag tree and dump everything.
After that it queries a couple of items and displays than in MsgBox dialogs, but you probably deleted that part since it was specific to the original sample JSON document.
If JbDump has a problem I don't see it. Did you alter it? When you break try View|Call Stack... to walk back and find out where DumpText was called from. What are the values of Name, Level, JB.Count, and ItemIndex?
Without a sample file that produces this problem there isn't a lot we can do remotely.
You can try make regexp-replacements of personal data.
Have never worked with regexp so a non-starter.
Was looking at a possible Search / Replace but Not sure amount effort involved.
I would think any Firefox bookmark file would give the same problems as IMHO it is more in their JSON format than in my data.
dilettante
Give me a couple days to see what I can come up with.
Without a sample file that produces this problem there isn't a lot we can do remotely.
If my data agree, if Firefox bookmark format is issue then any Firefox JSON bookmark file should give same error. Firefox appears to use arrays of objects (children) which may be nested fairly deep.
Last edited by vb6forever; Jan 2nd, 2018 at 03:00 PM.
No, other than to substitute path to bookmarks.json which I copied to same directory as the program.
When you break try View|Call Stack... to walk back and find out where DumpText was called from. What are the values of Name, Level, JB.Count, and ItemIndex?
Did three different breaks and followed Call Stack each time to JbDump
Checked the values for the variables suggested at each break.
All variables at EACH break had different values, but values look good -- from my bookmarks.json file.
=================
When I run Demo2 using the bookmarks.json file the left side "RTB" is stable and appears to show the bookmarks.json file (source) correctly from a cursory review. the right side "RTB" is the one that scrolls continuously as if stuck in a loop.
==================
After the 3 breaks ran again until appeared locked.
IGNORE THE FOLLOWING - POSTED IN ERROR because:
Since I broke on JbTest I would expect JbDump to have "Subscript out of Range" errors
and other variables to be questionable
==================================================
In checking JbDump the key issue appears to be "Subscript out of Range"
Code:
<< This following line and any other line with JB.Item(ItemIndex)
<< in JbDump shows as "Subscript out of Range"
If TypeOf JB.Item(ItemIndex) Is JsonBag Then
The other variables had values of:
Name = ""
ItemIndex = 0
JB.Count = 8
Last edited by vb6forever; Jan 3rd, 2018 at 08:17 AM.
Hi, Wonder if anyone can help.
I am using jsonbag and works very well. However, i send a query to a website and expect to get a list of stuff back.
This all works good. However if i send an incorrect code i get a json respone that gives me
P.Item("name") = "Not Found"
If when i check P.Item("name") = "Not Found" everything works and i exit the sub , but when i send a valid query and
everything is ok i get P.Item(Row).Item("xxxxxxx")
How do i check the error raised when P.Item("name") is not even returned.
I am using VB6 and get Runtime error 5 . invalid call or procedure.
i have tried checking Not IsNull(P.Item("name")) and some other variations but the only way i can
see is to use Goto err handler which i did not want to do.
Is there a way to catch this error of an item not being avail.
Nice Library. Has anyone used it to serialize a recordset? Any examples?
The problem with this is that something like an ADO Recordset is incredibly far richer than JSON.
JSON is so feature poor it is hard to know where to begin. Just look at data types:
JSON only has one numeric type: "number." That's instead of bytes, 16-bit and 32-bit integers, single-precision and double precision floating point, and more. JSON has no byte array. JSON has no date and time types. The list just goes on and on and on. Most of the culprit here is the incredibly type-poor JavaScript that JSON is based upon.
JSON lacks all kinds of metadata. For example a Recordset tracks whether a row has been modified, which is important when marshalling data back to a server for updating so you can send only the modified rows back... and if you send it all back the server can see which rows are to be updated to the underlying datastore at its end. The Fields within a Recordset also carry lots of metadata like the data type, ActualSize and DefinedSize, NumericScale, Precision, the Value and OriginalValue and UnderlyingValue, and more.
If you really want to serialize ADO Recordsets you may be far better off using one of the two formats it supports natively: ADO's own XML format or its ADTG binary format (far more compact).
Now, if you must have JSON and your needs are really meager you can cobble something up. However it is hard to imagine any generic way of doing this for all Recordsets. You must make massive compromises and those must be chosen for every use case.
Nothing says you can't invent some sort of JSON schema for doing this, much as ADO has its XML schema for representing Recordsets. i haven't seen anyone even attempt it yet though. There just isn't enough demand.
I suspect most people dealing with JSON are also dealing with servers that can't handle a Recordset anyway. So in that case they just use some ad hoc JSON schema that implements some tiny fraction of the metadata, if any at all, and live with the data type limitations.
But in that case there just isn't much to it. Any example would have to imply so many assumptions about the specific application as to be meaningless, probably useless for any other application.
Look, I think there is a bug in the Exists method of the last version, copy this code and replace the Exists procedure:
Code:
Public Function Exists(ByVal Key As Variant) As Boolean
Dim Name As String
If VarType(Key) = vbString Then
On Error Resume Next
Name = Names.Item(PrefixHash(Key))
Else
On Error Resume Next
Name = Names.Item(Key)
End If
Exists = Err.Number = 0
Err.Clear
End Function
About how to use it in chain:
Code:
If JB.Exists("sample") Then
If JB("sample").Exists("fudge") Then
Debug.Print JB.Item("sample").Item("fudge")
' Or
Debug.Print JB("sample")("fudge")
End If
End If
The word .Item is optional. (whether you put it or not it works anyway)
Look, I think there is a bug in the Exists method of the last version, copy this code and replace the Exists procedure:
Code:
Public Function Exists(ByVal Key As Variant) As Boolean
Dim Name As String
If VarType(Key) = vbString Then
On Error Resume Next
Name = Names.Item(PrefixHash(Key))
Else
On Error Resume Next
Name = Names.Item(Key)
End If
Exists = Err.Number = 0
Err.Clear
End Function
About how to use it in chain:
Code:
If JB.Exists("sample") Then
If JB("sample").Exists("fudge") Then
Debug.Print JB.Item("sample").Item("fudge")
' Or
Debug.Print JB("sample")("fudge")
End If
End If
The word .Item is optional. (whether you put it or not it works anyway)
thanks Eduardo. If JB("sample").Exists("fudge") Then was what i needed. Did not change the Exists though. left it as is and works fine
Code:
Public Function Exists(ByVal Key As Variant) As Boolean
Dim Hash As Long
Dim PrefixedKey As String
Dim Name As String
If VarType(Key) = vbString Then
HashData StrPtr(Key), Len(Key) * 2, VarPtr(Hash), 4
PrefixedKey = Right$("0000000" & Hex$(Hash), 8) & Key
On Error Resume Next
Name = Names.Item(PrefixedKey)
Else
On Error Resume Next
Name = Names.Item(Key)
End If
Exists = Err.Number = 0
Err.Clear
End Function
Normally you don't expose JSON to users any more than they should be looking at XML, INI, or any other persistence format. These are meant to store things like program settings that seldom change, descriptions of things like user interface layouts, or as data interchange formats.
If you really want this for some weird reason though it seems simple enough, for example:
Here I used different icon images to illustrate whether a node contains an "Object," "Array," "Property," or "Element." Blue for parent nodes and red for leaf nodes.
Last edited by dilettante; Mar 5th, 2019 at 02:07 PM.
Normally you don't expose JSON to users any more than they should be looking at XML, INI, or any other persistence format. These are meant to store things like program settings that seldom change, descriptions of things like user interface layouts, or as data interchange formats.
If you really want this for some weird reason though it seems simple enough, for example:
Here I used different icon images to illustrate whether a node contains an "Object," "Array," "Property," or "Element." Blue for parent nodes and red for leaf nodes.
thanks dilettante, that's just what i was looking for. i am trying to make a little app to help me create code that gets the json from web data.
usually i go through the json picking what i want and some times its hard to get the right combination
ie p.item("root").item("blah").item("bitmore")
then sometimes i create a for next to load in arrays of data and type this all manually.
With this i can create a rightclick on a node and poss create the path and bits of code i need to paste into my own apps
saves me typing and trial and error to get the right path.
Here I used different icon images to illustrate whether a node contains an "Object," "Array," "Property," or "Element." Blue for parent nodes and red for leaf nodes.
Don't suppose you would have any example of syntax highlighting json similar to this