Ricky Bobby
Ricky Bobby

Reputation: 7608

xslt test on a parameter of a tag

I would like to create a template in xslt with a condition on the parameter of the tag I am matching.

for exemple: If I have the tags <par class="class1"> and <par class="class2">

I would like to create a template like this :

<xsl:template match="par">
 <xsl:if test="class=class1">
  <fo:block
    space-before="3pt"
    space-after="3pt">

    <xsl:apply-templates />

  </fo:block>
 </xsl:if>
 <xsl:otherwise>
  <fo:block
    space-before="10pt"
    space-after="10pt">

    <xsl:apply-templates />

  </fo:block>
 </xsl:otherwise>
</xsl:template>

But it doesn't work. How can I test on the parameter of the tag ?

thanks in advance.

Upvotes: 2

Views: 1697

Answers (4)

Christopher Creutzig
Christopher Creutzig

Reputation: 8774

The technical term for these “parameters” is “attributes” (just in case that helps for future searches) and you refer to them with @class etc.

Also note that <xsl:otherwise> is not for <xsl:if>, but for <xsl:choose>:

<xsl:template match="par">
  <xsl:choose>
    <xsl:when test="@class='class1'">
      <fo:block
        space-before="3pt"
        space-after="3pt">

        <xsl:apply-templates />

      </fo:block>
    </xsl:when>
    <xsl:otherwise>
      <fo:block
        space-before="10pt"
        space-after="10pt">

        <xsl:apply-templates />

      </fo:block>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Or, to better show the actual differences,

<xsl:template match="par">
  <fo:block>
    <xsl:choose>
      <xsl:when test="@class='class1'">
        <xsl:attribute name='space-before'>3pt</xsl:attribute>
        <xsl:attribute name='space-after'>3pt</xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name='space-before'>10pt</xsl:attribute>
        <xsl:attribute name='space-after'>10pt</xsl:attribute>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

Upvotes: 2

Flynn1179
Flynn1179

Reputation: 12075

You can actually use a different template rather than using <xsl:if>. Like this:

<xsl:template match="par[@class='class1']">
  ..
</xsl:template>

<xsl:template match="par">
  ..
</xsl:template>

The second template is used for any par elements that are not matched by the first. Although the second template can match all par elements, it is overridden by the first because the latter is more specific.

Upvotes: 3

Phillip Kovalev
Phillip Kovalev

Reputation: 2487

At first <xsl:if/> is "standalone" instruction. You can use xsl:choose, if you needs in the default case.

In your code xsl:if test xpath are invalid. Use @attribute_name for attribute access and single quotes for string literals.

Fixed code:

<xsl:template match="par">
 <xsl:choose>
 <xsl:when test="@class = 'class1'">
  <fo:block
    space-before="3pt"
    space-after="3pt">
    <xsl:apply-templates />
  </fo:block>
 </xsl:when>
 <xsl:otherwise>
  <fo:block
    space-before="10pt"
    space-after="10pt">
    <xsl:apply-templates />
  </fo:block>
 </xsl:otherwise>
 <xsl:choose>
</xsl:template>

But there is more elegant solution for you task:

<xsl:template match="par">
    <fo:block
      space-before="10pt"
      space-after="10pt">

        <xsl:if test="@class = 'class1'">
            <xsl:attribute name="space-before" select="'3pt'"/>
            <xsl:attribute name="space-after" select="'3pt'"/>
        </xsl:if>

        <xsl:apply-templates />

    </fo:block>
</xsl:template>

Upvotes: 4

Fishcake
Fishcake

Reputation: 10754

You access attributes using @ and you can test the value of an attribute as follows:

<xsl:if test="@class = 'class1'">
    ....
</xsl:if>

or check if an attribute exists using

<xsl:if test="@class">
   ...
</xsl:if>

Upvotes: 1

Related Questions