Re: [xsl] XSL question

Subject: Re: [xsl] XSL question
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 28 Mar 2002 12:23:17 +0000
Hi Manoj,

> The tag value "CLOSING CONDITIONS:" can appear as value of any of
> the ConditionText tags, but after the "PRIOR CONDITIONS". The XSL
> stylesheet should locate the "CLOSING CONDITIONS:" value, and insert
> 3 new predefined fixed ConditionText nodes after that node. All the
> remaining ConditionText nodes will show this change in the result
> tree by having their count incremented as shown in the transformed
> XML below:

Crikey, that's a... *novel* XML structure. I think that the easiest
thing to do is to have a template that matches all the ConditionTextN
elements:

<xsl:template match="*[starts-with(name(), 'ConditionText')]">
  ...
</xsl:template>

Then you can test which kind of condition text it is, falling into
three categories:

  - the ConditionTextN element whose value is "CLOSING CONDITIONS:"
    (in which case it should be copied and the three new elements
    inserted)

  - before the ConditionTextN element whose value is "CLOSING
    CONDITIONS:" (in which case it should get copied)

  - after the ConditionTextN element whose value is "CLOSING
    CONDITONS:" (in which case it should be copied, but with its index
    number increased by 3)

You can have an xsl:choose to test which of the three conditions you
fall into. You can test whether a node is before the "CLOSING
CONDITIONS:" one by seeing if it has a following sibling whose value
is "CLOSING CONDITIONS:":

<xsl:template match="*[starts-with(name(), 'ConditionText')]">
  <xsl:choose>
    <xsl:when test=". = 'CLOSING CONDITIONS:'">
      ...
    </xsl:when>
    <xsl:when test="following-sibling::*[. = 'CLOSING CONDITIONS:']">
      ...
    </xsl:when>
    <xsl:otherwise>
      ...
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

You need to be able to work out the index of the ConditionTextN
element, obviously, which you can do by taking the substring after
'ConditionText' in the name:

  <xsl:variable name="index"
                select="substring-after(name(), 'ConditionText')" />

You can copy elements completely with xsl:copy-of, and create elements
with new names using an attribute value template in the name attribute
of the xsl:element instruction. For example, you can create the
copies, with updated index, of the nodes following the 'CLOSING
CONDITIONS:' element with the following:

  <xsl:element name="ConditionText{$index + 3}">
    <xsl:copy-of select="node()" />
  </xsl:element>

So a template that you could use would be:

<xsl:template match="*[starts-with(name(), 'ConditionText')]">
  <xsl:variable name="index"
                select="substring-after(name(), 'ConditionText')" />
  <xsl:choose>
    <xsl:when test=". = 'CLOSING CONDITIONS:'">
      <xsl:copy-of select="." />
      <xsl:element name="ConditionText{$index + 1}">
        This is Standard Condition 1
      </xsl:element>
      <xsl:element name="ConditionText{$index + 2}">
        This is Standard Condition 2
      </xsl:element>
      <xsl:element name="ConditionText{$index + 3}">
        This is Standard Condition 3
      </xsl:element>
    </xsl:when>
    <xsl:when test="following-sibling::*[. = 'CLOSING CONDITIONS:']">
      <xsl:copy-of select="." />
    </xsl:when>
    <xsl:otherwise>
      <xsl:element name="ConditionText{$index + 3}">
        <xsl:copy-of select="node()" />
      </xsl:element>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread