[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: To control node duplication

Subject: Re: To control node duplication
From: George Cristian Bina <george@xxxxxxxxxxxxx>
Date: Tue, 13 Jan 2009 09:45:09 +0200
Re:  To control node duplication
In XSLT 2.0 you can use something like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>


  <xsl:template match="level">
    <xsl:variable name="level" select="."/>
    <xsl:for-each select="string-to-codepoints(states)">
      <xsl:apply-templates select="$level" mode="copy">
        <xsl:with-param name="state" select="."/>
      </xsl:apply-templates>
    </xsl:for-each>
  </xsl:template>

  <xsl:template match="node() | @*" mode="copy">
    <xsl:param name="state"/>
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" mode="copy">
        <xsl:with-param name="state" select="$state"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="elem1/text()" mode="copy">
    <xsl:param name="state"/>
    <xsl:value-of select="."/>
    <xsl:text>_</xsl:text>
    <xsl:value-of select="codepoints-to-string($state)"/>
  </xsl:template>
</xsl:stylesheet>

on your sample input it gives

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

Best Regards,
George
--
George Cristian Bina
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

nick public wrote:
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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.