Cybersecurity
DevOps Cloud (ADM)
IT Operations Cloud
Identity Manager has very good facilities for dealing with XML files right out of the box. JSON parsing, however, usually means using an XPATH token to call your own custom ECMA code to parse the JSON object and return values and/or XML that can be manipulated by the IDM driver's policies.
To make it easier to retrieve data from a JSON document, and simplify to an extent generating one from an instance XDS document, a library with a set of pre-defined ECMA functions was put together and is available at https://github.com/fchierad/IDM-ECMAlib . That set contains 3 files:
To use the library all we need is to download the file JSONlib-JS.js, open it in a text editor then on your Designer project right-click on your driverset's Library and select New > ECMAScript. Give the object a name, click OK. Copy the contents of the file JSONlib-JS.js into the newly created ECMA object and save it. Deploy the same to your system to make it live and available.
To be able to call the functions from a driver you need to link that ECMAScript object you've just created to the driver. To do so go to the driver's properties > Driver Configuration > ECMA Script, click Add, browse to and select the object you've just created, click OK, click OK again to close the editor window.
As with all ECMA code in IDM driver policy we need to call the functions from inside XPath conditions/Actions/tokens, using the es: namespace in front of the function names. Given some of the functions provided return objects instead of primitives we will also be using the "Object" type local variable in some cases to store the results.
Of notice is that the file JSONlib-tests.xml is a completely self-contained DirXML-Script police with multiple tests to validate the ECMA library's function behaviors. Adding it to a driver and using policy simulator will give you a good set of examples on how to use the functions.
Most people that used JSON before are familiar with the JSON object ( ScriptVault.JSON on the RBPM back-end ) and its parse() and stringify() functions. That object is available on a driver's ECMA policies, unfortunately it cannot be accessed directly from XPath actions. To address that the first 2 functions in the library are JSONparse() and JSONstringify(). As the names imply they are simply wrappers to JSON.parse() and JSON.stringify().
So to convert a serialized representation of a JSON object into the object itself and store the same in a local variable we can use an action like
<do-set-local-variable name="var_parse" scope="policy">
<do-set-local-variable name="var_parse" scope="policy">
<arg-object> <token-xpath expression="es:JSONparse( '{"result":{"statusCode":"201","ReturnCode":"SUCCESS","Message":"Demoing JSONparse","list":[1,2,3],"objlist":[{"prop":"green"},{"prop":"yellow"},{"prop":"red"}] }}' )"/>
</arg-object>
</do-set-local-variable>
Nothing fancy so far. The main point of saving that result is for usage in other function that accept that object. To Serialize it back into a string just use
<do-set-local-variable name="var_stringify" scope="policy">
<arg-string>
<token-xpath expression="es:JSONstringify( $var_parse )"/>
</arg-string>
</do-set-local-variable>
and we will get back a compact representation of the JSON object as a string.
As seen above most examples in this document will be built on the following JSON (pretty-formatted for ease of reading):
{
"result": {
"statusCode": "201",
"ReturnCode": "SUCCESS",
"Message": "Demoing JSONparse",
"list": [
1,
2,
3
],
"objlist": [
{
"prop": "green"
},
{
"prop": "yellow"
},
{
"prop": "red"
}
]
}
}
In most cases what we need is not to convert back and forth between object and string, it is to check if certain properties are available, and if so, if their values meet certain criteria. We need to process those values as well. To check if a property is present we will use JSONtest( inputJSON, whattotest ). To actually retrieve the property's value we will use JSONget( inputJSON, whattoget, returntype ). Both functions accept either an object or a serialized JSON string as the inputJSON parameter, and will convert internally to an object to operate. That is why it is useful to pre-convert a JSON that will be processed if you are going to use the functions more than once against the same JSON. The parameters 'whattoget' and 'whattotest' use regular ECMA notation to access object properties and array indexes.
The example below uses es:JSONtest( $var_parse, 'result.statusCode' ) to check if a property exists then es:JSONget( $var_parse, 'result.statusCode' ) to retrieve the value. Notice that we omitted the returntype on JSONget - that is an optional parameter that if omitted will default to 'raw'. Lucky this property value is a string, so we got back something meaningful from the call.
Null : Action: do-if().
Null : Evaluating conditions.
Null : ECMA debug: JSONtest(): Parsing: "result", type: string
Null : ECMA debug: JSONtest(): Parsing: "statusCode", type: string
Null : (if-xpath true "es:JSONtest( $var_parse, 'result.statusCode' )") = TRUE.
Null : Performing if actions.
Null : Action: do-trace-message(level="0",token-xpath("es:JSONget( $var_parse, 'result.statusCode' )")).
Null : arg-string(token-xpath("es:JSONget( $var_parse, 'result.statusCode' )"))
Null : token-xpath("es:JSONget( $var_parse, 'result.statusCode' )")
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "statusCode", type: string
Null : Token Value: "201".
Null : Arg Value: "201".
Null :201
The ECMA debug messages are coded to appear only at trace level 5 and above, to allow us to run trace level 3 to debug driver issues without additional clutter.
On JSONget(), returntype can be 'string', 'number' or 'raw. String and Number will attempt to coerce the retrieved value to said ECMA primitives, and will not work as intended if you apply them to an object. 'raw' will return the selected piece as is so that we can process it further with other functions. Attempting to get a location that does not exist in the JSON will result in an empty string being returned:
Null : Action: do-set-local-variable("var_parse",scope="policy",arg-object(token-xpath("es:JSONparse( '{"result":{"statusCode":"201","ReturnCode":"SUCCESS","Message":"Demoing JSONparse","list":[1,2,3],"objlist":[{"prop":"green"},{"prop":"yellow"},{"prop":"red"}] }}' )"))).
Null : arg-object(token-xpath("es:JSONparse( '{"result":{"statusCode":"201","ReturnCode":"SUCCESS","Message":"Demoing JSONparse","list":[1,2,3],"objlist":[{"prop":"green"},{"prop":"yellow"},{"prop":"red"}] }}' )"))
Null : token-xpath("es:JSONparse( '{"result":{"statusCode":"201","ReturnCode":"SUCCESS","Message":"Demoing JSONparse","list":[1,2,3],"objlist":[{"prop":"green"},{"prop":"yellow"},{"prop":"red"}] }}' )")
Null : Action: do-trace-message(level="0",token-xpath("es:JSONget( $var_parse, 'result.statusCode.values' )")).
Null : arg-string(token-xpath("es:JSONget( $var_parse, 'result.statusCode.values' )"))
Null : token-xpath("es:JSONget( $var_parse, 'result.statusCode.values' )")
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "statusCode", type: string
Null : ECMA debug: JSONget(): Parsing: "values", type: string
Null : ECMA debug: JSONget(): could not find property "values" in the current object location.
Null : Token Value: "".
Null : Arg Value: "".
Given the above it is possible to retrieve and test a property's value (assuming it is a string or a number) directly in the XPath expression. Keep in mind that the returned value returns to the XPath expression so our comparison operations follow the XPath ones, not the ECMA set of comparison operators. So to check if the statusCode is the string 201 we would do:
Null : Action: do-if().
Null : Evaluating conditions.
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "statusCode", type: string
Null : (if-xpath true "es:JSONget( $var_parse, 'result.statusCode', 'string' ) = "200"") = FALSE.
Null : Performing else actions.
Null : Action: do-if().
Null : Evaluating conditions.
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "statusCode", type: string
Null : (if-xpath true "es:JSONget( $var_parse, 'result.statusCode', 'string' ) = "201"") = TRUE.
Null : Performing if actions.
Null : Action: do-trace-message(level="0","Found the desired status code").
Null : arg-string("Found the desired status code")
Null : token-text("Found the desired status code")
Null : Arg Value: "Found the desired status code".
Null :Found the desired status code
To check if the property's value (coerced as a number) is greater than or lower than a value we could do:
Null : Action: do-if().
Null : Evaluating conditions.
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "statusCode", type: string
Null : (if-xpath true "es:JSONget( $var_parse, 'result.statusCode', 'number' ) > 200") = TRUE.
Null : Performing if actions.
Null : Action: do-trace-message(level="0","Found the desired status code").
Null : arg-string("Found the desired status code")
Null : token-text("Found the desired status code")
Null : Arg Value: "Found the desired status code".
Null :Found the desired status code
Null : Action: do-if().
Null : Evaluating conditions.
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "statusCode", type: string
Null : (if-xpath true "es:JSONget( $var_parse, 'result.statusCode', 'number' ) < 200") = FALSE.
Null : Performing else actions.
And an example getting a property that contains an array in its path. Remember that ECMA arrays start at 0, whereas XPath index references start at 1. So [2] in the example below is the 3rd element of the array:
Null : Action: do-trace-message(level="0",token-xpath("es:JSONget( $var_parse, 'result.objlist[2].prop' )")).
Null : arg-string(token-xpath("es:JSONget( $var_parse, 'result.objlist[2].prop' )"))
Null : token-xpath("es:JSONget( $var_parse, 'result.objlist[2].prop' )")
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "objlist", type: string
Null : ECMA debug: JSONget(): Parsing: "2", type: number
Null : ECMA debug: JSONget(): Parsing: "prop", type: string
Null : Token Value: "red".
Null : Arg Value: "red".
Null :red
The last 2 functions we will discuss are arrayToNodeset( arr ) and instanceXMLtoJSON( instnodeset, returntype, buildstructure, inserttype ). There are other functions in the library, most of which are used internally by the functions discussed in this article.
arrayToNodeset, as the name implies, converts an ECMA array to an DOM nodeset. The nodeset has 1 <array> element as its root node, and zero or more <element> nodes with the contents of the array. It is important to note that if an array element is an object, that object will be serialized to a JSON string and added as text under the current node.
Parsing a simple array put together with JSONparse:
Null : Action: do-trace-message(level="0","This approach is a mistake, since we are passing a string as the function parameter, despite looking like an array:
" token-xpath("es:arrayToNodeset( '[ 1, 2, 3 ]' )")).
Null : arg-string("This approach is a mistake, since we are passing a string as the function parameter, despite looking like an array:
" token-xpath("es:arrayToNodeset( '[ 1, 2, 3 ]' )"))
Null : token-text("This approach is a mistake, since we are passing a string as the function parameter, despite looking like an array:
")
Null : token-xpath("es:arrayToNodeset( '[ 1, 2, 3 ]' )")
Null : ECMA debug: arrayToNodeset(): The provided parameter is not an ECMA Array.
Null : Token Value: "".
Null : Arg Value: "This approach is a mistake, since we are passing a string as the function parameter, despite looking like an array:
".
Null :This approach is a mistake, since we are passing a string as the function parameter, despite looking like an array:
Null : Action: do-trace-message(level="0","Now it works. Also, function compostion by using a function's result as another funcitons input:
" token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONparse( '[ 1, 2, 3 ]' ) )"))).
Null : arg-string("Now it works. Also, function compostion by using a function's result as another funcitons input:
" token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONparse( '[ 1, 2, 3 ]' ) )")))
Null : token-text("Now it works. Also, function compostion by using a function's result as another funcitons input:
")
Null : token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONparse( '[ 1, 2, 3 ]' ) )"))
Null : token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONparse( '[ 1, 2, 3 ]' ) )"))
Null : token-xpath("es:arrayToNodeset( es:JSONparse( '[ 1, 2, 3 ]' ) )")
Null : Token Value: {<array>}.
Null : Arg Value: {<array>}.
Null : Token Value: "<array>
<element>1</element>
<element>2</element>
<element>3</element>
</array>".
Null : Arg Value: "Now it works. Also, function compostion by using a function's result as another funcitons input:
<array>
<element>1</element>
<element>2</element>
<element>3</element>
</array>".
Null :Now it works. Also, function compostion by using a function's result as another funcitons input:
<array>
<element>1</element>
<element>2</element>
<element>3</element>
</array>
Parsing a simple array retrieved with JSONget:
Null : Action: do-trace-message(level="0",token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.list' ) )"))).
Null : arg-string(token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.list' ) )")))
Null : token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.list' ) )"))
Null : token-xml-serialize(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.list' ) )"))
Null : token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.list' ) )")
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "list", type: string
Null : Token Value: {<array>}.
Null : Arg Value: {<array>}.
Null : Token Value: "<array>
<element>1</element>
<element>2</element>
<element>3</element>
</array>".
Null : Arg Value: "<array>
<element>1</element>
<element>2</element>
<element>3</element>
</array>".
Null :<array>
<element>1</element>
<element>2</element>
<element>3</element>
</array>
Parsing an array of objects retrieved with JSONget. Notice that since the result returned is a nodeset we can directly apply /element like we would with a nodeset local variable with the same structure:
Null : Action: do-for-each(arg-node-set(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.objlist' ) )/element"))).
Null : arg-node-set(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.objlist' ) )/element"))
Null : token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.objlist' ) )/element")
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "objlist", type: string
Null : Token Value: {<element>,<element>,<element>}.
Null : Arg Value: {<element>,<element>,<element>}.
Null : Performing actions for local-variable(current-node) = <element>.
Null : Action: do-trace-message(level="0",token-local-variable("current-node")).
Null : arg-string(token-local-variable("current-node"))
Null : token-local-variable("current-node")
Null : Token Value: "{"prop":"green"}".
Null : Arg Value: "{"prop":"green"}".
Null :{"prop":"green"}
Null : Performing actions for local-variable(current-node) = <element>.
Null : Action: do-trace-message(level="0",token-local-variable("current-node")).
Null : arg-string(token-local-variable("current-node"))
Null : token-local-variable("current-node")
Null : Token Value: "{"prop":"yellow"}".
Null : Arg Value: "{"prop":"yellow"}".
Null :{"prop":"yellow"}
Null : Performing actions for local-variable(current-node) = <element>.
Null : Action: do-trace-message(level="0",token-local-variable("current-node")).
Null : arg-string(token-local-variable("current-node"))
Null : token-local-variable("current-node")
Null : Token Value: "{"prop":"red"}".
Null : Arg Value: "{"prop":"red"}".
Null :{"prop":"red"}
Due to how $current-node and $current-value are presented back to the ECMA engine, and how JSONget parses its input, for JSONget to work inside the for each loop we would need a construct like es:JSONget( es:JSONparse( $current-node ), 'prop' ). Trace excerpt:
Null : Action: do-for-each(arg-node-set(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.objlist' ) )/element"))).
Null : arg-node-set(token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.objlist' ) )/element"))
Null : token-xpath("es:arrayToNodeset( es:JSONget( $var_parse, 'result.objlist' ) )/element")
Null : ECMA debug: JSONget(): Parsing: "result", type: string
Null : ECMA debug: JSONget(): Parsing: "objlist", type: string
Null : Token Value: {<element>,<element>,<element>}.
Null : Arg Value: {<element>,<element>,<element>}.
Null : Performing actions for local-variable(current-node) = <element>.
Null : Action: do-trace-message(level="0",token-local-variable("current-node")).
Null : arg-string(token-local-variable("current-node"))
Null : token-local-variable("current-node")
Null : Token Value: "{"prop":"green"}".
Null : Arg Value: "{"prop":"green"}".
Null :{"prop":"green"}
Null : Action: do-trace-message(level="0",token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )")).
Null : arg-string(token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )"))
Null : token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )")
Null : ECMA debug: JSONget(): Parsing: "prop", type: string
Null : Token Value: "green".
Null : Arg Value: "green".
Null :green
Null : Performing actions for local-variable(current-node) = <element>.
Null : Action: do-trace-message(level="0",token-local-variable("current-node")).
Null : arg-string(token-local-variable("current-node"))
Null : token-local-variable("current-node")
Null : Token Value: "{"prop":"yellow"}".
Null : Arg Value: "{"prop":"yellow"}".
Null :{"prop":"yellow"}
Null : Action: do-trace-message(level="0",token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )")).
Null : arg-string(token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )"))
Null : token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )")
Null : ECMA debug: JSONget(): Parsing: "prop", type: string
Null : Token Value: "yellow".
Null : Arg Value: "yellow".
Null :yellow
Null : Performing actions for local-variable(current-node) = <element>.
Null : Action: do-trace-message(level="0",token-local-variable("current-node")).
Null : arg-string(token-local-variable("current-node"))
Null : token-local-variable("current-node")
Null : Token Value: "{"prop":"red"}".
Null : Arg Value: "{"prop":"red"}".
Null :{"prop":"red"}
Null : Action: do-trace-message(level="0",token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )")).
Null : arg-string(token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )"))
Null : token-xpath("es:JSONget( es:JSONparse( $current-node ), 'prop' )")
Null : ECMA debug: JSONget(): Parsing: "prop", type: string
Null : Token Value: "red".
Null : Arg Value: "red".
Null :red
The function instanceXMLtoJSON() would merit its own article. Running the tests XML file provided through policy simulator will give more examples on how to use the same. For this article will show the most basic usage followed by a fairly complex example.
Simple instanceXML conversion:
Null : Applying rule 'instanceXMLtoJSON test 001'.
Null : Action: do-set-local-variable("var_instancexml",notrace="true",scope="policy",arg-node-set(token-xml-parse("<instance class-name="User" src-dn="\Users\Samuel">
<association>1012</association>
<attr attr-name="Surname">
<value>Jones</value>
</attr>
<attr attr-name="cn">
<value>Samuel</value>
</attr>
<attr attr-name="Given Name">
<value>Samuel</value>
</attr>
<attr attr-name="Telephone Number">
<value>555-1212</value>
<value>555-1764</value>
</attr>
</instance>"))).
Null : -- trace suppressed --
Null : Action: do-trace-message(level="0",token-xpath("es:instanceXMLtoJSON( $var_instancexml )")).
Null : arg-string(token-xpath("es:instanceXMLtoJSON( $var_instancexml )"))
Null : token-xpath("es:instanceXMLtoJSON( $var_instancexml )")
Null : ECMA debug: nodesetLV2ElementImpl(): Top node => "#document"
Null : ECMA debug: nodesetLV2ElementImpl(): Iterating #document node - new Top node => "instance"
Null : ECMA debug: instanceXMLtoJSON(): Found => Surname:Jones
Null : ECMA debug: instanceXMLtoJSON(): Found => cn:Samuel
Null : ECMA debug: instanceXMLtoJSON(): Found => Given Name:Samuel
Null : ECMA debug: instanceXMLtoJSON(): Found => Telephone Number:555-1212,555-1764
Null : Token Value: "{"Surname":"Jones","cn":"Samuel","Given Name":"Samuel","Telephone Number":["555-1212","555-1764"]}".
Null : Arg Value: "{"Surname":"Jones","cn":"Samuel","Given Name":"Samuel","Telephone Number":["555-1212","555-1764"]}".
Null :{"Surname":"Jones","cn":"Samuel","Given Name":"Samuel","Telephone Number":["555-1212","555-1764"]}
Fairly complex example:
Null : Applying rule 'instanceXMLtoJSON'.
Null : Action: do-set-local-variable("var_instancexml",notrace="true",scope="policy",arg-node-set(token-xml-parse("<instance class-name="User" src-dn="\TREE\org\user">
<association>xxx</association>
<attr attr-name="Full Name">
<value type="string">user name</value>
<value>another name</value>
</attr>
<attr attr-name="Surname">
<value>name</value>
</attr>
<attr attr-name="OU">
<value>Science</value>
</attr>
<attr attr-name="binary">
<value>uk GHULT0GM9 RZzXkAltA==</value>
</attr>
<attr attr-name="numeric">
<value type="int">20</value>
</attr>
<attr attr-name="Language">
<value>
<component name="string">ES</component>
<component name="string">EN</component>
</value>
</attr>
<attr attr-name="booleantest">
<value type="state">true</value>
<value type="state">false</value>
<value type="state">tRuE</value>
<value type="state">FaLsE</value>
<value type="state">TRUE</value>
<value type="state">FALSE</value>
</attr>
<attr attr-name="DirXML-SPEntitlements">
<value>
<component name="string">joe</component>
<component name="string">johnson</component>
<component name="string">{A0A8EE3D-675B-444e-9FD0-320CC756DC6D}</component>
</value>
</attr>
<attr attr-name="nrfResourceHistory">
<value type="structured">
<component name="volume">Resource001.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE</component>
<component name="nameSpace">1</component>
<component name="path"><history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>Testing</req_desc><action>granted</action></history></component>
</value>
<value type="structured">
<component name="volume">Resource002.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE</component>
<component name="nameSpace">1</component>
<component name="path"><history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>More tests</req_desc><action>granted</action></history></component>
</value>
</attr>
<attr attr-name="ACL">
<value type="structured">
<component name="protectedName">allowAliasToAncestor</component>
<component name="trustee">data\sa\uaadmin</component>
<component name="privileges">02</component>
</value>
</attr>
</instance>"))).
Null : -- trace suppressed --
Null : Action: do-trace-message(level="0",token-xpath("es:instanceXMLtoJSON( $var_instancexml, 'serialized', 'data:list["so.me:value"]more:test:value.somethingelse', 'advanced' )")).
Null : arg-string(token-xpath("es:instanceXMLtoJSON( $var_instancexml, 'serialized', 'data:list["so.me:value"]more:test:value.somethingelse', 'advanced' )"))
Null : token-xpath("es:instanceXMLtoJSON( $var_instancexml, 'serialized', 'data:list["so.me:value"]more:test:value.somethingelse', 'advanced' )")
Null : ECMA debug: nodesetLV2ElementImpl(): Top node => "#document"
Null : ECMA debug: nodesetLV2ElementImpl(): Iterating #document node - new Top node => "instance"
Null : ECMA debug: instanceXMLtoJSON(): Found => Full Name:user name,another name
Null : ECMA debug: instanceXMLtoJSON(): Found => Surname:name
Null : ECMA debug: instanceXMLtoJSON(): Found => OU:Science
Null : ECMA debug: instanceXMLtoJSON(): Found => binary:uk GHULT0GM9 RZzXkAltA==
Null : ECMA debug: instanceXMLtoJSON(): Found => numeric:20
Null : ECMA debug: instanceXMLtoJSON(): Found => Language:[object Object]
Null : ECMA debug: instanceXMLtoJSON(): Found => booleantest:true,false,true,false,true,false
Null : ECMA debug: instanceXMLtoJSON(): Found => DirXML-SPEntitlements:[object Object]
Null : ECMA debug: instanceXMLtoJSON(): Found => nrfResourceHistory:[object Object],[object Object]
Null : ECMA debug: instanceXMLtoJSON(): Found => ACL:[object Object]
Null : Token Value: "{"data":[{"so.me":{"more:test":{"somethingelse":{"Full Name":["user name","another name"],"Surname":"name","OU":"Science","binary":"uk GHULT0GM9 RZzXkAltA==","numeric":20,"Language":{"string":["ES","EN"]},"booleantest":[true,false,true,false,true,false],"DirXML-SPEntitlements":{"string":["joe","johnson","{A0A8EE3D-675B-444e-9FD0-320CC756DC6D}"]},"nrfResourceHistory":[{"volume":"Resource001.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE","nameSpace":"1","path":"<history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>Testing</req_desc><action>granted</action></history>"},{"volume":"Resource002.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE","nameSpace":"1","path":"<history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>More tests</req_desc><action>granted</action></history>"}],"ACL":{"protectedName":"allowAliasToAncestor","trustee":"data\\sa\\uaadmin","privileges":"02"}}}}}]}".
Null : Arg Value: "{"data":[{"so.me":{"more:test":{"somethingelse":{"Full Name":["user name","another name"],"Surname":"name","OU":"Science","binary":"uk GHULT0GM9 RZzXkAltA==","numeric":20,"Language":{"string":["ES","EN"]},"booleantest":[true,false,true,false,true,false],"DirXML-SPEntitlements":{"string":["joe","johnson","{A0A8EE3D-675B-444e-9FD0-320CC756DC6D}"]},"nrfResourceHistory":[{"volume":"Resource001.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE","nameSpace":"1","path":"<history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>Testing</req_desc><action>granted</action></history>"},{"volume":"Resource002.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE","nameSpace":"1","path":"<history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>More tests</req_desc><action>granted</action></history>"}],"ACL":{"protectedName":"allowAliasToAncestor","trustee":"data\\sa\\uaadmin","privileges":"02"}}}}}]}".
Null :{"data":[{"so.me":{"more:test":{"somethingelse":{"Full Name":["user name","another name"],"Surname":"name","OU":"Science","binary":"uk GHULT0GM9 RZzXkAltA==","numeric":20,"Language":{"string":["ES","EN"]},"booleantest":[true,false,true,false,true,false],"DirXML-SPEntitlements":{"string":["joe","johnson","{A0A8EE3D-675B-444e-9FD0-320CC756DC6D}"]},"nrfResourceHistory":[{"volume":"Resource001.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE","nameSpace":"1","path":"<history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>Testing</req_desc><action>granted</action></history>"},{"volume":"Resource002.ResourceDefs.RoleConfig.AppConfig.rbpm.driverset1.system.IDM45LABTREE","nameSpace":"1","path":"<history><action_tm>20180127210929Z</action_tm><req_tm>19700118132447Z</req_tm><req>cn=uaadmin,ou=sa,o=data</req><req_desc>More tests</req_desc><action>granted</action></history>"}],"ACL":{"protectedName":"allowAliasToAncestor","trustee":"data\\sa\\uaadmin","privileges":"02"}}}}}]}
Hope you've enjoyed the article and come to use the library. Please report bugs and request enhancements at https://github.com/fchierad/IDM-ECMAlib/issues . Entering issues will allow the library to grow via your bug reports and enhancement requests.