Reputation: 2493
Parsing JSON data in XSLT and attempting to get a specified keys value. I have controlled in the XML map that XSLT produces as part of parsing JSON and I do find the key with value "car".
Problem: I do not get the expected value in the result.
You find the code here: xsltfiddle
Same code is added here:
JSON:
<data>
{
"storage": {
"car": "Volvo"
}
}
</data>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:output method="xml" indent="yes" html-version="5"/>
<!-- Block all data that has no user defined template -->
<xsl:mode on-no-match="shallow-skip"/>
<!-- Transform JSON to XML -->
<xsl:template match="data">
<xsl:apply-templates select="json-to-xml(.)/*"/>
<!-- Select -->
<xsl:value-of select="//*[@key='car']"/>
</xsl:template>
<!-- Print map -->
<!--
<xsl:template match="*[@key = 'storage']">
<xsl:copy-of select=".."/>
</xsl:template>
-->
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
Wanted result
<?xml version="1.0" encoding="UTF-8"?>
Volvo
Upvotes: 0
Views: 150
Reputation: 163352
You wrote in a comment:
Still don't understand though why my code does not work
And indeed, we often make the mistake of giving you code that works, without telling you what you did wrong.
Your mistake is here:
<xsl:apply-templates select="json-to-xml(.)/*"/>
<xsl:value-of select="//*[@key='car']"/>
You have two instructions, and you're expecting the second instruction to operate on the result of the first. But that's not how XSLT works; each of these instructions works on the same input (specifically, each of them takes the data
element in the source document as input). So //*[@key='car']
doesn't select anything, because there's nothing that matches this in the original source document.
If you want the second instruction to apply to the result of the first, you can put the result of the first in a variable:
<xsl:variable name="converted-input">
<xsl:apply-templates select="json-to-xml(.)/*"/>
</xsl:variable>
<xsl:value-of select="$converted-input//*[@key='car']"/>
or, as @sspsujit has done, you can collapse it all into a single instruction, because the xsl:apply-templates
isn't actually doing anything of interest.
Upvotes: 1
Reputation: 163352
I wouldn't convert the JSON to XML for this: I would parse it to an XDM map, and then lookup the value in the map. Thus:
<xsl:value-of select="parse-json(.)?storage?car"/>
Upvotes: 2
Reputation: 301
I think you need this:
<!-- Transform JSON to XML -->
<xsl:template match="data">
<!-- Select -->
<xsl:value-of select="json-to-xml(.)//*[@key='car']"/>
</xsl:template>
to get:
<?xml version="1.0" encoding="UTF-8"?>Volvo
Upvotes: 1