p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   XSLT (http://p2p.wrox.com/forumdisplay.php?f=86)
-   -   How to MOVE sub-element to preceding-sibling’s last sub-element (http://p2p.wrox.com/showthread.php?t=82965)

lkd March 15th, 2011 09:07 AM

How to MOVE sub-element to preceding-sibling’s last sub-element
 
I need an XSL rule to move an XML sub-element to print before the preceding-sibling’s last sub-element (<tools> or it could be <parts>). My if statement is:

Quote:

IF (/work/prelim/tools OR /work/prelim/parts) AND /work/main/planning exist in the XML,
THEN
MOVE /work/main/planning to print BEFORE (/work/prelim/tools OR /work/prelim/parts)
OTHERWISE just <apply-templates />.
I've tried several things, but I just can't get it to print before <tools> (or in some files, it's <parts>).

XML is as follows:

Code:

    <work>
        <prelim>
            <code>ABC</code>
            <source>DEF</source>
            <tools>Includes codes for a table</tools>
        </prelim>
        <main>
            <planning>Text for Planning</planning>
            <p>blah blah blah</p>
        </main>
    </work>

I want my output to be as follows (if the above condition exists):

Code:

    <work>
        <prelim>
            <code>ABC</code>
            <source>DEF</source>
            <planning>Text for Planning</planning>
            <tools>Includes codes for a table</tools>
        </prelim>
        <main>
            <p>blah blah blah</p>
        </main>
    </work>

Can anyone help me on how to achieve this?

Thanks in advance!!

lkd

Martin Honnen March 15th, 2011 09:16 AM

Code:

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

<xsl:template match="work/prelim/tools | work/prelim/parts">
  <xsl:copy-of select="../following-sibling::main/planning"/>
  <xsl:call-template name="identity"/>
</xsl:template>

<xsl:template match="work[prelim/tools | prelim/parts]/main/planning"/>

might suffice but would copy "planning" twice if both "tools" and "parts" exist.

lkd March 15th, 2011 10:47 AM

How to MOVE sub-element to preceding-sibling’s last sub-element
 
Thanks!! Your code copied <planning> to the correct location but did not remove it from <main> (sigh...why doesn't XSL just have a move element?!). I tried the following rule, but it still did not remove <planning> from <main>:

Code:

<xsl:template match="main">
    <xsl:copy>
        <xsl:apply-template select=@* | node() [not(planning)]"/>
    </xsl:copy>
</xsl:template>


Martin Honnen March 15th, 2011 10:56 AM

Did you use the code as posted? When I use the stylesheet
Code:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
 
<xsl:template match="@* | node()" name="identity">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="work/prelim/tools | work/prelim/parts">
  <xsl:copy-of select="../following-sibling::main/planning"/>
  <xsl:call-template name="identity"/>
</xsl:template>

<xsl:template match="work[prelim/tools | prelim/parts]/main/planning"/>

</xsl:stylesheet>

against the input
Code:

    <work>
        <prelim>
            <code>ABC</code>
            <source>DEF</source>
            <tools>Includes codes for a table</tools>
        </prelim>
        <main>
            <planning>Text for Planning</planning>
            <p>blah blah blah</p>
        </main>
    </work>

with Saxon 6.5.5 the output is
Code:

<?xml version="1.0" encoding="utf-8"?><work>
        <prelim>
            <code>ABC</code>
            <source>DEF</source>
            <planning>Text for Planning</planning><tools>Includes codes for a table</tools>
        </prelim>
        <main>

            <p>blah blah blah</p>
        </main>
    </work>

So that way the element "planning" is removed from the "main" element.

lkd March 15th, 2011 11:00 AM

Never mind...I found the resolution. Duh...all I had to do was create an empty planning rule for <planning>.

Thanks so much for your help!!

lkd

Martin Honnen March 15th, 2011 11:11 AM

Well both code samples I posted already had the empty template
Code:

<xsl:template match="work[prelim/tools | prelim/parts]/main/planning"/>
for the "planning" element.

lkd March 15th, 2011 11:15 AM

Thanks again!! I like yours better and it did work like I wanted. Yours was a new trick I didn't know!

lkd


All times are GMT -4. The time now is 04:07 PM.

Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.