Results 1 to 6 of 6

Thread: How to write an XSLT stylesheet to make the node with id=5

  1. #1
    Join Date
    Jul 2006
    Posts
    128

    How to write an XSLT stylesheet to make the node with id=5

    Suppose you have this document:

    <root>
    <node id="1">
    <node id="4"/>
    <node id="5"/>
    </node>
    <node id="2"/>
    <node id="3"/>
    </root>

    How to write an XSLT
    stylesheet to make the node with id=5 a child of
    the node with id=2?

    The resulting document should look as follows:

    <root>
    <node id="1">
    <node id="4"/>
    </node>
    <node id="2">
    <node id="5"/>
    </node>
    <node id="3"/>
    </root>

    Thanks,

  2. #2
    Join Date
    Jan 2008
    Posts
    1,521

    Re: XSLT: Moving node in document

    mostly you want to copy

    <xsl:template match="*">
    <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>

    but you want to lose id 5

    <xsl:template match="node[@id='5']"/>

    and you want it to appear again in id 2

    <xsl:template match="node[@id='2']">
    <xsl:copy>
    <xsl:copy-of select="@*|//node[@id='5']"/>
    <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>

  3. #3
    Join Date
    Jul 2006
    Posts
    128

    Re: How to write an XSLT stylesheet to make the node with id=5

    Thanks, simple and elegant.

    Could you give me a hint how to parameterise this?

    The following approach doesn't seem to work:

    ------------------------------------------------------
    <xsl:stylesheet
    version="1.0"
    xmlnssl="http://www.w3.org/1999/XSL/Transform">

    <xslaram name="nodeparent" />
    <xslaram name="nodeid" />

    <xsl:template match="*">
    <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="node[@id='{$nodeid}']"/>

    <xsl:template match="node[@id='{$nodeparent}']">
    <xsl:copy>
    <xsl:copy-of select="@*|//node[@id='{$nodeid}']"/>
    <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>


    Easy enough to put an <xsl:choose> construct inside the identity
    transform, and ignore the node satisfying "@id = $nodeid'. But how can
    we then add that node to $nodeparent?

  4. #4
    Join Date
    Feb 2008
    Posts
    1,852

    Re: How to write an XSLT stylesheet to make the node with id=5

    Not yet tested, but ...

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml"
    xmlnssl="http://www.w3.org/1999/XSL/Transform">

    <!-- put "id=5" into "id=2" -->
    <xsl:template match="*[@id='2']">
    <xsl:copy>
    <xsl:apply-templates select="*[@id='5']"/>
    <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    </xsl:template>

    <!-- match "id=5" and do NOTHING -->
    <xsl:template match="*[@id='5']"/>

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

  5. #5
    Join Date
    Jan 2008
    Posts
    1,521

    Re: How to write an XSLT stylesheet to make the node with id=5

    I knew you were going to ask that

    <xsl:template match="node[@id='{$nodeid}']"/>


    that would never work, { _never_ has any special meaning in an XPath
    expression or, as here, in an XSLT pattern. They are used to _surround_
    Xpath expressions in XSLT Attribute value templates, but they are not
    part of Xpath.

    The syntax should be

    <xsl:template match="node[@id=$nodeid]"/>

    except that in a failed attempt to prevent circular definitions, any use
    of variables in match patterns is outlawed in XSLT1 so you can't do
    this. (You will be able to do it in XSLT2 as this restriction is
    dropped in XSLT2 draft.)

    Similarly for

    <xsl:copy-of select="@*|//node[@id='{$nodeid}']"/>

    except that here of course you can use a variable in XSLT1:

    <xsl:copy-of select="@*|//node[@id=$nodeid]"/>

    The reason why the restriction on variables in match patterns is
    annoying (and will be removed) is that it's easy to circumvent it, in
    this case for example you could do:

    <xsl:template match="node">
    <xsl:choose>
    <xsl:when test="@id='$nodeid"/>
    <xsltherwise>
    <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:if test="@id=$nodeparent">
    <xsl:copy-of select="//node[@id='$nodeid']"/>
    </xsl:if>
    <xsl:apply-templates/>
    </xsl:copy>
    </xsltherwise>
    </xsl:choose>
    </xsl:template>

  6. #6
    Join Date
    Jan 2008
    Posts
    1,521

    Re: How to write an XSLT stylesheet to make the node with id=5

    oops sorry I left in two of your quotes

    <xsl:copy-of select="//node[@id='$nodeid']"/>
    ^ ^


    <xsl:copy-of select="//node[@id=$nodeid]"/>

Similar Threads

  1. change colors of a stylesheet (.css) in Opera Browser
    By Rikin J in forum Technology & Internet
    Replies: 3
    Last Post: 12-08-2013, 01:34 PM
  2. Replies: 3
    Last Post: 15-09-2011, 08:37 AM
  3. Replies: 6
    Last Post: 09-10-2010, 01:59 PM
  4. Make sure disk is not full or write-protected" error????
    By Taanusiya in forum Operating Systems
    Replies: 4
    Last Post: 06-10-2010, 01:18 PM
  5. Converting CDATA Node into Text Node
    By Jagdish Gada in forum Software Development
    Replies: 3
    Last Post: 07-12-2009, 09:54 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Page generated in 1,713,541,766.61179 seconds with 17 queries