XSLT to generate another XSLT script

xml, xslt

Solution

To write one XSLT that outputs another you either need to generate the output elements using `<xsl:element>`, e.g.

<xsl:element name="xsl:text">

or use `<xsl:namespace-alias>` if you want to use literal result elements. The XSLT spec has an example:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">

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

<xsl:template match="/">
  <axsl:stylesheet>
    <xsl:apply-templates/>
  </axsl:stylesheet>
</xsl:template>

Any `<axsl:...>` elements in the stylesheet will become `<xsl:...>` in the output.

Problem

In this thread I refer to my last thread: Convert XML to CSV using XSLT - dynamic columns. The XSLT script in the refered thread works fine but with a large XML document the performance is not good. Now I want to write an XSLT script that outputs another XSLT script which will output the final CSV file. Question: How to write the first XSLT script? The output should look like the following: ``` <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/*"> <xsl:text>Name;</xsl:text> <xsl:text>Brother;</xsl:text> <xsl:text>Sister</xsl:text> <-- this part is dynamic --> <xsl:apply-templates select="Person" /> </xsl:template> <xsl:template match="Person"> <xsl:value-of select="Name" /> <xsl:value-of select="Brother" /> <xsl:value-of select="Sister" /> <-- this part is dynamic too --> <xsl:text>&#10;</xsl:text> </xsl:template> </xsl:stylesheet> ``` The input XML file is the same like in the refered thread: ``` <Person> <Name>John</Name> <FamilyMembers> <FamilyMember> <Name>Lisa</Name> <Type>Sister</Type> </FamilyMember> <FamilyMember> <Name>Tom</Name> <Type>Brother</Type> </FamilyMember> </FamilyMembers> </Person> <Person> <Name>Daniel</Name> <FamilyMembers> <FamilyMember> <Name>Peter</Name> <Type>Father</Type> </FamilyMember> </FamilyMembers> </Person> ``` For every different type element there should be one line like the following in the resulting XSLT script: ``` <xsl:text>Type;</xsl:text> ```

Original source