Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: XML vs. JSON serialization  (Read 14812 times)
Enrico S.
Posts: 40


« on: October 22, 2019, 05:16:49 pm »

Hi,
If I'm not in error, in XML serialization field names and fields order must match in both XML node structure and Genero record structure,  while in JSON serialization these match are not required.
Is it a choice ?
Could we expect in a future release these XML constraints to be overcome ?

Best Regards.
Enrico
Reuben B.
Four Js
Posts: 1116


« Reply #1 on: October 24, 2019, 12:17:20 am »

There are some options that relax the requirements, see the two ignoreunknown attributes here http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/r_gws_XmlSerializer_option_flags.html as well as attributes such as XMLOptional  that may help you.

However if your question is more about the order, and you are asking as with an example like the following ...

Code
  1. IMPORT util
  2. IMPORT xml
  3. MAIN
  4. DEFINE r RECORD
  5.    field1 STRING,
  6.    field2 STRING
  7. END RECORD
  8. DEFINE d1,d2 xml.DomDocument
  9.  
  10.    -- JSON
  11.    INITIALIZE r TO NULL
  12.    CALL util.JSON.parse('{"field1":"value1","field2":"value2"}',r)
  13.    DISPLAY r.field1, r.field2
  14.    -- Swap order around, can still parse
  15.    INITIALIZE r TO NULL
  16.    CALL util.JSON.parse('{"field2":"value2","field1":"value1"}',r)
  17.    DISPLAY r.field1, r.field2
  18.  
  19.    --XML
  20.    INITIALIZE r TO NULL
  21.    LET d1 = xml.DomDocument.create()
  22.    CALL d1.loadFromString("<root><field1>value1</field1><field2>value2</field2></root>")
  23.    CALL xml.Serializer.DomToVariable(d1.getDocumentElement(),r)
  24.    DISPLAY r.field1, r.field2
  25.  
  26.    -- Swap order around, cannot parse
  27.    INITIALIZE r TO NULL
  28.    LET d2 = xml.DomDocument.create()
  29.    CALL d2.loadFromString("<root><field2>value2</field2><field1>value1</field1></root>")
  30.    CALL xml.Serializer.DomToVariable(d2.getDocumentElement(),r)
  31.    DISPLAY r.field1, r.field2
  32.  
  33. END MAIN

why you can swap the order for JSON and it will still parse, but if you swap the order for XML it won't parse. 

I think the answer to this lies by using the XMLALL attribute http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_gws_XML_attribute_XMLAll.html

By changing the above example to have

Code
  1. DEFINE r RECORD ATTRIBUTES(XMLAll)
  2.  

then it runs which I suspect is what you are after.

Why do you need the option, and why does it not work by default, note that with a JSON string, the element name is unique, whilst the XML Node Name is not necessarily unique

Reuben

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
Enrico S.
Posts: 40


« Reply #2 on: October 24, 2019, 08:36:22 am »

Hi, Reuben. I understand.
The "why" is that in past third-party developers was asking me to ignore fields order (they was manually serializing SOAP messages).
Now I simply wanted to go in deep to this argument and I was asking for your point of view.
But I was not considering the uniqueness of JSON node names against XML.
Thanks a lot for your answer.
Enrico.
Rene S.
Four Js
Posts: 112


« Reply #3 on: October 24, 2019, 08:39:20 am »

Some fun:

Code
  1. OPTIONS SHORT CIRCUIT
  2. IMPORT util
  3.  
  4. MAIN
  5.    DEFINE r RECORD
  6.        field1 STRING,
  7.        field2 STRING
  8.    END RECORD
  9.    DEFINE jo util.JSONObject
  10.  
  11.    LET jo = xml2json(
  12.            "<root><field1>value1a</field1><field2>value2a</field2></root>")
  13.    CALL jo.toFGL(r)
  14.    DISPLAY r.*
  15.  
  16.    LET jo = xml2json(
  17.            "<root><field2>value2b</field2><field1>value1b</field1></root>")
  18.    CALL jo.toFGL(r)
  19.    CALL jo.toFGL(r)
  20.    DISPLAY r.*
  21. END MAIN
  22.  
  23. FUNCTION xml2json(xml STRING) RETURNS util.JSONObject
  24.    DEFINE doc om.DomDocument
  25.    DEFINE root, node, chars om.DomNode
  26.    DEFINE jo util.JSONObject
  27.  
  28.    LET doc = om.DomDocument.createFromString(xml)
  29.    LET root = doc.getDocumentElement()
  30.    LET jo = util.JSONObject.create()
  31.    LET node = root.getFirstChild()
  32.    WHILE node IS NOT NULL
  33.        IF (chars := node.getFirstChild()) IS NOT NULL
  34.            AND chars.getTagName() == "@chars" THEN
  35.            CALL jo.put(node.getTagName(), chars.getAttribute("@chars"))
  36.        END IF
  37.        LET node = node.getNext()
  38.    END WHILE
  39.    RETURN jo
  40. END FUNCTION
  41.  

Code:
$ fglcomp test && fglrun test
value1avalue2a
value1bvalue2b
Enrico S.
Posts: 40


« Reply #4 on: October 25, 2019, 03:02:16 pm »

Nice.
Not so well explained in manuals the meaning of @chars attribute name of Text nodes (it is new for me), but searching in deep from your sample it is possible to understand.
Every time I ask something, you let me know a further small brick.
Thanks again.
Enrico
Sebastien F.
Four Js
Posts: 545


« Reply #5 on: October 28, 2019, 09:31:33 am »

Hello Enrico,

Your suggestions to improve the documentation are welcome.

Please use the feedback facility when something is missing or unclear.

We talk about the @chars attribute and tagname in the following pages:

    http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_ClassDomNode_getAttribute.html
    http://4js.com/online_documentation/fjs-fgl-manual-html/index.html#fgl-topics/c_fgl_ClassDomDocument_createChars.html

However, I agree that it is missing here:

    http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_ClassDomNode_getTagName.html

Do you expect something else?

Seb
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines