RolfBly
RolfBly

Reputation: 3862

Assign long piece of repeated XSLT to variable

I'm transforming some XML into a SQL query, using this template. It does what it should do.

<xsl:template match="link-info">
  UNION<br/>
  SELECT 
  <xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/>.term, thesau_term.term,<br/>
  COUNT(<xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/>.term) AS frequency<br/>
  FROM <xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/><br/>
  INNER JOIN thesau_term on <xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/>.term = thesau_term.priref<br/>
  GROUP BY <xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/>.term, thesau_term.term
  <br/>
</xsl:template>

The template generates SELECT clauses for a whole bunch of tables. As you can see, table names are constructed from the XML using:

<xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/>

which is repeated 5 times. Not DRY. Now, neither xsl:variable nor xsl:param seem to be intended for making things more readable, something like

<xsl:mysnippet name="table_name">
  <xsl:value-of select="//database-info/@name"/>_<xsl:value-of select="key('Tagkey', forwardreferencetag)"/>
</xsl:mysnippet>

and then instead of that long clause something like this whenever required.

 <xsl:mysnippet name="$table_name" />

Is there any way of doing this within XSLT 1.0?

Upvotes: 0

Views: 50

Answers (1)

Michael Kay
Michael Kay

Reputation: 163468

This is how I might write it in XSLT 3.0

<xsl:template match="link-info" expand-text="yes">
  <xsl:variable name="name_tag" select="concat(//database-info/@name,
       key('Tagkey', forwardreferencetag))" as="xs:string"/>
  UNION<br/>
  SELECT {$name_tag}.term, thesau_term.term,<br/>
  COUNT({$name_tag}.term) AS frequency<br/>
  FROM {$name_tag}><br/>
  INNER JOIN thesau_term on {$name_tag}.term = thesau_term.priref<br/>
  GROUP BY {$name_tag}.term, thesau_term.term
  <br/>
</xsl:template>

With XSLT 1.0 you can't do the curly-brace expand-text thing, but a variable is still quite an improvement:

SELECT <xsl:value-of select="$name_tag"/>.term, thesau_term.term,<br/>

Upvotes: 2

Related Questions