tags:

views:

57

answers:

2

I would like to process a frame element in my source xml file using XSLT 2.0 (Saxon 9.1.0.7). If the frame element contains a renderer attribute I need to send this from the frame template to another named template, otherwise I would like to send a default renderer value to the named template.

So in the source xml file I could have the following, in which case I would like to send a default value to the named template as a parameter:

<frame id="menu_frame_1">

Or, if the renderer attribute is defined in the source xml doc, then I would like to send that instead of the default:

<frame id="menu_frame_1" renderer="KONtx.element.Container">

The problem I am having is I don't know how to conditionally choose either the default, or the defined attribute if it exists and pass it to the named template. I tried using a xsl:choose within a call-template, but this is not allowed. Also, I would move the choose outside the call-template, and set a variable with either the default, or attribute value, but variables are immutable so i'm not sure how to handle that case either. Below is the template for the frame element, and the named template I am trying to call. Any help is appreciated. Thanks.

<xsl:template match="frame">    
    <!-- Call new object start named template below -->
    <xsl:call-template name="newObjectStart">
        <xsl:with-param name="id"><xsl:value-of select="@id" /></xsl:with-param>

        <xsl:choose>
            <xsl:when test="@renderer">
                <xsl:with-param name="renderer">
                    <xsl:value-of select="@renderer" />
                </xsl:with-param>
            </xsl:when>
            <xsl:otherwise>
                <xsl:with-param name="renderer">KONtx.element.Container</xsl:with-param> 
            </xsl:otherwise>
        </xsl:choose>
    </xsl:call-template>

    ...
</xsl:template>


<!-- New Object Start Named Template -->
<xsl:template name="newObjectStart">
    <xsl:param name="id" />
    <xsl:param name="renderer" />

    <xsl:text>var </xsl:text>
    <xsl:value-of select="$id" />
    <xsl:text> = </xsl:text>    
    <xsl:text>new </xsl:text> 
    <xsl:value-of select="$renderer" /> 
    <xsl:text>({</xsl:text>
</xsl:template>
+1  A: 

You have to put the <xsl:choose> inside the <xsl:with-param> instead of outside.

<xsl:template match="frame">
  <!-- Call new object start named template below -->
  <xsl:call-template name="newObjectStart">
    <xsl:with-param name="id">
      <xsl:value-of select="@id" />
    </xsl:with-param>
    <xsl:with-param name="renderer">
      <xsl:choose>
        <xsl:when test="@renderer">
          <xsl:value-of select="@renderer" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="'KONtx.element.Container'" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:with-param>
  </xsl:call-template>

  ...
</xsl:template>
Martin Liversage
Thanks, this works and makes perfect sense. I'm trying to get my head wrapped around how to use xslt.
Steve
A: 

Try this


    <xsl:choose>
        <xsl:when test="@renderer">
           <xsl:call-template name="newObjectStart">
              <xsl:with-param name="id"><xsl:value-of select="@id" /></xsl:with-param>
              <xsl:with-param name="renderer"><xsl:value-of select="@renderer" /></xsl:with-param>
           </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
           <xsl:call-template name="newObjectStart">
              <xsl:with-param name="id"><xsl:value-of select="@id" /></xsl:with-param>
              <xsl:with-param name="renderer">KONtx.element.Container</xsl:with-param> 
           </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:call-template>

...

Stephen Newman