Forum

Posted by
Stephen R. van den Berg  -  September 2012
If I throw the following into a variable:

 <set variable="q.m">
  <json-parse>
   {"0":55,
    "1":"Foo"
   }
  </json-parse>
 </set>

It results in:
m=([ /* 2 elements */
  "0": 55,
  "1": "Foo",
])

The trouble is, when trying to access this using:
  &q.m.0; or &q.m.1;

does not work, because it interprets the 0 and the 1 as integers, and looks
for the integer key 0 and 1 in the mapping (which is not present, obviously).

How to work around this?
My first thought was to change Roxen to check for string keys as well as
integer keys when retrieving (and then make one of them leading).
Because, currently, it already does magic the other way around (it prefers
the integer version if it is a number, and uses the string index key if
it is not a number).

Trying to find the spot where this is done is not so easy, though.
Any hints?  I looked at server/etc/modules/Variable.pmod/module.pmod
Or other thoughts?
 
Posted by
Stephen R. van den Berg  -  September 2012
Ok, found this:
  array(string|int) parse_user_var (string var, void|string|int scope_name)
  //! Parses the var string for scope and/or subindexes according to
  //! the RXML rules, e.g. @tt{"scope.var.1.foo"@}. Returns an array
  //! where the first entry is the scope, and the remaining entries
  //! are the list of indexes. If @[scope_name] is a string, it's used
  //! as the scope and the var string is only used for subindexes. A
  //! default scope is chosen as appropriate if var cannot be split,
  //! unless @[scope_name] is a nonzero integer in which case it's
  //! returned in the scope position in the array (useful to detect
  //! whether @[var] actually was split or not).
  //!
  //! @tt{".."@} in the var string quotes a literal @tt{"."@}, e.g.
  //! @tt{"yow...cons..yet"@} is separated into @tt{"yow."@} and
  //! @tt{"cons.yet"@}. Any subindex that can be parsed as a signed
  //! integer is converted to it. Note that it doesn't happen for the
  //! first index, since a variable name in a scope always is a string.

Which explains that it is converted into an integer at this point, and
is not easily changed into a string.

So the simplest point of attack would be the json-parse function,
which I could ask not to create string references if it encounters integer
keys in a mapping (or force, by default, perhaps).
 
Posted by
Stephen R. van den Berg  -  September 2012
That turned out to be a sort-of dead end, because it hands it off
to Standards.JSON.decode().

Further investigation reveals that:
 <insert variable="q.m" index="2" />

actually uses a string to index the mapping, and therefore accesses the correct
member.
Problem solved.
 
1
Search this thread: