Re: [xsl] Json to xml

Subject: Re: [xsl] Json to xml
From: "dvint@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 14 Mar 2025 19:08:30 -0000
I was just going to post that I found a way using tunnel paramters. I added this template in the included XSLT file and it does the trick because at this point I am now only dealing with XML content.

<xsl:template match="/">
<xsl:apply-templates>
<xsl:with-param name="PROPERTIES" select="/j:map/j:map[@key='properties']"
tunnel="yes"/>
</xsl:apply-templates>
</xsl:template>


Thanks for letting me work through this with everyone.

..dan


On 2025-03-14 12:01, Martin Honnen martin.honnen@xxxxxx wrote:
On 14/03/2025 18:20, dvint@xxxxxxxxx wrote:
In trying to build a small sample I have found where the problem is
coming from. It looks like this might be a timing issue of when the
stylesheet is read vs when the json-to-sml() file is triggered and
that XML becomes available to evaluate.

At the top of the included XSLT is this

\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- Remeber thsi content to lookup details later -->
\xA0\xA0\xA0\xA0<xsl:variable name="PROPERTIES"
select="/j:map/j:map[@key='properties']"/>

I use this value to lookup details that are linked to much further
down and deeply nested. This works prefectly when using this XSLT
standalone with the generated XML file.

I'm guessing what happens when it is included in the main XSLT, that
this variable is being set based upon the JSON file that the main XSLT
is called with.

In the main XSLT, I moved this declaration out of the template so the
variable is global:

<xsl:variable name="MAPFILE" select="json-to-xml(., map { 'escape' :
true() })"/>

I then modified the PROPERTIES variable to use $MAPFILE and it now works.

\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <!-- Remeber thsi content to lookup details later -->
\xA0\xA0\xA0\xA0<xsl:variable name="PROPERTIES"
select="$MAPFILE/j:map/j:map[@key='properties']"/>

BUT it is now no longer possible to run the second stylesheet standalone.

So, I've found the problem and need to find a better way to capture
this information.



A clean way with XSLT, in my view, with your approach to have the same stylesheet directly process an XML representation of some JSON and to include it in a main module that produces the XML representation would be to use a tunnel parameter e.g.


<xsl:template match="document-node(j:map)">


\xA0\xA0\xA0 <xsl:apply-templates>

\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:with-param name="PROPERTIES" tunnel="yes"
select="j:map/j:map[@key='properties']"/>

\xA0\xA0\xA0\xA0 </xsl:apply-templates>

</xsl:template>


then where you used your global variable in a template you will need to make sure you declare a tunnel template parameter

\xA0\xA0 <xsl:param name="PROPERTIES" tunnel="yes"/>

and you should be able to use $PROPERTIES.


From the main stylesheet you can keep the



\xA0\xA0\xA0 <xsl:template match="data"> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:variable name="MAPFILE" select="json-to-xml(.)"/> \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:variable name="connectorID" select="$MAPFILE/j:map/j:string[@key='serviceName']"/>

\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:result-document method="xml"\xA0 indent="yes"
href="{concat($connectorID, '.xml')}" >
\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:copy-of select="$MAPFILE"/>
\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:result-document>

\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:result-document method="text" href="{concat($connectorID,
'.adoc')}">
\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:apply-templates select="$MAPFILE"/>
\xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:result-document>
\xA0\xA0\xA0 </xsl:template>

Current Thread