In developerWorks DataPower forum thread Need Help With XML to Json Transformation the question was raised on how to transform XML to JSON.
I did propose a transformation from XML to JSONX and then making use of "store:///jsonx2json.xsl" transformation to get the JSON output:
Pros of that approach:
- genereric where possible (xsl:templates with mode "number" and "string")
- specific where needed (where are arrays, where are objects? arguments, see this posting)
- gets all difficulties resolved for free (JSON string escaping rules, performance of these escapings)
- just need to focus on transform XML->JSONX, no need to think about JSON
Now I wanted to know "the price" of that approach.
First I created bigger input by "./rdp87 1000 >rdp87.1000.xml" with this script:
$ cat rdp87
echo " <ver>2.0</ver>"
echo " <source>31</source>"
for((i=1; i<=$1; ++i))
echo " <data>"
echo " <table>"$t"</table>"
echo " <batch>"$b"</batch>"
echo " </data>"
From my initial XML-->JSONX-->JSON transformation rdp87.2.xsl:
I created "all-in-one" stylesheet for doing the XML-->JSON transformation rdp87.3.xsl:
Now I created two XML FW on a box with 22.214.171.124 firmware containing the (performance) fix for APAR IC90781 from May 2013 fixpack.
Both services used an XML Manager with "Profile Rule" in XML Manager's Compile Options policy.
Finally I did:
- clear stylesheet cache for XML manager "profile"
send 1000 requests to service by
$ time for((f=1;f<=1000;++f)); do curl --data-binary @rdp87.1000.xml http://dp7-l3:port ; echo; done
- switch to "Status->XML Processing->Stylesheet Profiles" in WebGUI and take screenshot
Yes, the total time taken for rdp87.2.xsl (1961ms) in the templates is by a factor of 2.66 greater than that of rdp87.3.xsl (735ms).
But that does only make an effect if the whole operation of a service is just XML->JSON conversion.
Typically in real live services other operations like AAA, SLM actions or other will happen.
If this is the case, then the (small) runtime overhead added is outweighted by maintainability and ease of stylesheet in my eyes.
This is the really small diff:
$ diff rdp87.2.xsl rdp87.2a.xsl
> <xsl:import href="store:///jsonx2json.xsl"/>
< <xsl:copy-of select="dp:transform('store:///jsonx2json.xsl', $jsonx)"/>
> <xsl:apply-templates select="$jsonx/*" />