XSLT: Conditional attribute Value handling


The following isn't working as intended:

<xsl:template match="xs:complexType">
  <xsl:param name="prefix" />

  <xsl:if test="$prefix='core'">
    <xsl:variable name="prefix" select=""/>

  <xs:complexType name="{concat($prefix, @name)}">
    <xsl:apply-templates select="node()" />
  <xsl:apply-templates select=".//xs:element" />

The idea is that if the prefix variable value is "core", I don't want it to be added onto the name attribute value. Any other value, I'd like to be added. IE:

<xs:complexType name="coreBirthType">

…is not acceptable, while the following would be:

<xs:complexType name="BirthType">

But I have to allow for this to occur:

<xs:complexType name="AcRecHighSchoolType">

I tried this in a block, but saxon complains about not finding a closing node:

  <xsl:when test="starts-with(.,'core')">
    <xs:complexType name="{@name)}">
    <xs:complexType name="{concat($prefix, @name)}">
  <xsl:apply-templates select="node()" />

What is the best way to handle this?

Best Solution

In XSLT, as a pure language with no side effects, variables are immutable. You cannot change a variable value. If you declare another <xsl:variable> with the same name, you define a new variable which shadows the old one.

Here's how you can do this:

<xsl:param name="prefix" />

<xsl:variable name="prefix-no-core">
  <xsl:if test="$prefix != 'core'">
    <xsl:value-of select="$prefix" />

<xs:complexType name="{concat($prefix-no-core, @name)}">
Related Question