[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] To control node duplication


Subject: [xsl] To control node duplication
From: "nick public" <nickpubl@xxxxxxxxx>
Date: Tue, 13 Jan 2009 02:34:18 +0100

Hi people.
I have the following need.
I have to duplicate a sub-tree basing of an element <states> contained
into the source XML.

<root>
  <level>
    <states>456</states>
    <start>
      <elem1>element</elem1>
    </start>
  </level>
</root>


For each <level> copy, the <elem1> element have to contain the
corresponding states byte.
In this case I've create a XML target containing 3 <level> element and
for each copy, the <elem1> element contains the 4, 5 and 6 status.

The target for the example have to be like this:

<root>
  <level>
    <control>456</control>
    <start>
      <elem1>element_4</elem1>
    </start>
  </level>
  <level>
    <control>456</control>
    <start>
      <elem1>element_5</elem1>
    </start>
  </level>
  <level>
    <control>456</control>
    <start>
      <elem1>element_6</elem1>
    </start>
  </level>
</root>

Now, I learned thanks to you how to copy the sub-tree. I haven't
problem with string processing.
My problem is to control the copy.
I need something like this (please, don't become frightened: it's the
minimal code and is commented)

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <!-- Load in a variable the states to manage -->
  <xsl:variable name='states' select ='root/level/states'/>

  <xsl:template match="level">
    <!-- Predisposes to manage all the three states
         passing as parameter each status to check in
         front to the states variable -->

    <!-- Invokes copyNode for the status 4.
         In copyNodes, if 4 is contained in states
         variable the level element will be copied
         otherwise no -->
    <xsl:call-template name='copyNode'>
      <xsl:with-param name='status' select='4'/>
    </xsl:call-template>

    <xsl:call-template name='copyNode'>
      <xsl:with-param name='status' select='5'/>
    </xsl:call-template>

    <xsl:call-template name='copyNode'>
      <xsl:with-param name='status' select='6'/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="copyNode">
    <xsl:param name='status'/>

    <!-- Checks if the current $status (4, 5 or 6)
         is contained in the $states.
         If yes, can copies the level element -->
    <xsl:if test='contains($states,$status)'>

      <xsl:choose>
        <!-- :-(( THIS when SEEMS NEVER PERFORMED :-(( -->
        <xsl:when test="self::elem1">
          <elem1>
            <!-- The elem1 text value have to be manipulated by $status -->
            <xsl:value-of select ='concat(substring(.,1,5),$status)'/>
          </elem1>
        </xsl:when>

        <xsl:otherwise>
          <xsl:copy-of select="."/>
        </xsl:otherwise>
      </xsl:choose>

     </xsl:if>
  </xsl:template>

</xsl:stylesheet>

The critical point is that the  <xsl:when test="self::elem1">  is
never reached and then I cannot operate the tranformation.


Could you help me URGENTLY?
Thanks a lot in advance.

Ciao. Nicola


Current Thread
Keywords
xml