Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use XSL to generate dynamic XSL that is executed within the same script?

Tags:

dynamic

xml

xslt

I want to dynamically create variables with dynamic names for later use in my transform, but to do this I'd need to dynamically generate XSL and then run it in the same script.

This is just a rough pseudo code example of what I'm looking for.

      <xsl:for-each select="//constants/constant" >
        <xsl:variable >
            <xsl:attribute name="name">
              <xsl:value-of select="@name"/>
            </xsl:attribute>
          <xsl:attribute name="select">
            <xsl:value-of select="@value"/>
          </xsl:attribute>
        </xsl:variable>
      </xsl:for-each>

Can I use XSL to dynamically build XSL to be run later in the same script?

Note: our XML is transformed via a batch process running a CL XSL transform engine; so just referencing an XSL stylesheet in the XSL document isn't an option.

like image 497
Frank Rosario Avatar asked Dec 10 '08 21:12

Frank Rosario


1 Answers

XSLT has a special built-in feature that supports generating output, which is XSLT itself.

This is the <xsl:namespace-alias> XSLT directive.

As explaiened by the XSLT 1.0 Spec.:

"

<!-- Category: top-level-element -->
<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />

A stylesheet can use the xsl:namespace-alias element to declare that one namespace URI is an alias for another namespace URI. When a literal namespace URI has been declared to be an alias for another namespace URI, then the namespace URI in the result tree will be the namespace URI that the literal namespace URI is an alias for, instead of the literal namespace URI itself. The xsl:namespace-alias element declares that the namespace URI bound to the prefix specified by the stylesheet-prefix attribute is an alias for the namespace URI bound to the prefix specified by the result-prefix attribute. Thus, the stylesheet-prefix attribute specifies the namespace URI that will appear in the stylesheet, and the result-prefix attribute specifies the corresponding namespace URI that will appear in the result tree. "

Here is a small example of a transformation that generates an xsl:stylesheet containing an xsl:variable, which is constructed in the wanted way:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xxx="my:dummyNS" exclude-result-prefixes="xxx"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:namespace-alias result-prefix="xsl" stylesheet-prefix="xxx"/>

 <xsl:template match="/*">
  <xxx:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xxx:variable name="{@name}">
    <xsl:value-of select="."/>
  </xxx:variable>
 </xxx:stylesheet>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the following XML document:

    <v name="myVarName">myValue</v>

the wanted result is produced:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="myVarName">myValue</xsl:variable>
</xsl:stylesheet>

Then the next step will be to launch in your "script" this dynamically generated XSLT transformation.

like image 152
Dimitre Novatchev Avatar answered Sep 29 '22 07:09

Dimitre Novatchev