Lisa
Lisa

Reputation: 77

How to add node in case of a particular attribute value

In my xsl there are already templates defined for elements like para, graphic etc. Example below:

    <xsl:template match="para">    
            <fo:block>
            <xsl:apply-templates />             
      </fo:block>
  </xsl:template>

But I want to add an extra node in case of a particular attribute value. For example, if the element has the attribute value of changeStatus = new, I need to add 'fo:change-bar-begin' element inside the other nodes. Example xml:

    <para changeStatus="new">
This is a paragraph that has change bars applied to the whole paragraph. </para>

The output should be:

<fo:block>
<fo:change-bar-begin change-bar-style="solid"/>
            This is a paragraph that has change bars applied to the whole paragraph.
<fo:change-bar-end/>            
      </fo:block>

I am using this code but it is overriding the earlier templates and removing the nodes(fo:block) defined in other templates.

<xsl:template match="para|graphic|attention">
    <xsl:choose>
        <xsl:when test="@changeStatus[.='new']">
            <fo:change-bar-begin change-bar-style="solid"/>
                <xsl:apply-templates />
                <fo:change-bar-end/>
                            </xsl:when>
                            <xsl:otherwise>
                    <xsl:apply-templates />
                </xsl:otherwise>
                            </xsl:choose>
</xsl:template>

Please suggest the best possible way to do this.

Edit: I realized that I cannot use two template matches for the same element and this is why one is overriding the other. I am now using this snippet but it does not seem to be working.

<xsl:template match="@changeStatus[.='new']">
                <fo:change-bar-begin change-bar-style="solid" change-bar-color="black" change-bar-offset="5pt" change-bar-placement="inside"/>
                <xsl:apply-templates />
                <fo:change-bar-end/>                    

                            </xsl:template>

Upvotes: 0

Views: 58

Answers (2)

Rupesh_Kr
Rupesh_Kr

Reputation: 3445

Try this:

<xsl:template match="para|graphic|attention">
    <fo:block>
        <xsl:choose>
            <xsl:when test="@changeStatus='new'">
                <fo:change-bar-begin change-bar-style="solid"/>
                <xsl:apply-templates />
                <fo:change-bar-end/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates />             
            </xsl:otherwise>
        </xsl:choose>
    </fo:block>
 </xsl:template>

For not to change existing template you can use priority in new template as

<xsl:template match="para[@changeStatus='new']" priority="10">
    <fo:block>
        <fo:change-bar-begin change-bar-style="solid"/>
        <xsl:apply-templates />
        <fo:change-bar-end/>
    </fo:block>
</xsl:template>

Upvotes: 1

Tim C
Tim C

Reputation: 70648

Consider making your current template a named template instead

<xsl:template name="checkStatus">
   <xsl:choose>
      <xsl:when test="@changeStatus='new'">
         <fo:change-bar-begin change-bar-style="solid"/>
            <xsl:apply-templates />
         <fo:change-bar-end/>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates />
      </xsl:otherwise>
    </xsl:choose>
</xsl:template>

Then, adjust your para matching template like so (you would do similar for the templates matching graphic and attention)

<xsl:template match="para">    
   <fo:block>
      <xsl:call-template name="checkStatus">             
   </fo:block>
</xsl:template>

Upvotes: 1

Related Questions