xsl-list
[Top] [All Lists]

[xsl] Copying parent nodes with different selection of their content

2007-04-25 07:55:25
Hi List,

This should be a really easy thing to do, I'm sure, but I'm having a blank spot today when it comes to XSLT, it seems. Perhaps some imperative twist in my mind stops me from writing down a straight solution (or I just never encountered the problem before, but I couldn't find it in my own archive).

Basically, I have the solution, but it is so awkward that I am sure that "there is a better way", esp. with XSLT. Take the dataset (see variable $copy-me in the XSLT sample) and consider a copy of the Document node for each Make-Toute-Seul-X node, without the other Make-Toute-Seul-X nodes. The result of the transformation is this (see the similar data, with changing Make-Toute-Seul-X elements):

(The original data is a SOAP envelope, and the envelope needs to be copied a couple of times for each occurrence of some node, which triggers a document in 'real' life)

OUTPUT:
<Header>
   <Meta/>
</Header>
<Body>
   <Document>
       <Preceding-1/>
       <Preceding-2/>
       <Make-Toute-Seul-1/>
       <Following-1/>
       <Following-2/>
   </Document>
   <Document>
       <Preceding-1/>
       <Preceding-2/>
       <Make-Toute-Seul-2/>
       <Following-1/>
       <Following-2/>
   </Document>
   <Document>
       <Preceding-1/>
       <Preceding-2/>
       <Make-Toute-Seul-3/>
       <Following-1/>
       <Following-2/>
   </Document>
</Body>



The XSLT looks like this and can be run on itself (I had other incarnations, equally bad, anybody with a nicer solution that feels more like 'XSLT'?). I'd like to move the duplicated logic about the nodes Make-Toute-Seul-X to a single location, to make maintenance a breeze.


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0"> <xsl:output indent="yes" /> <xsl:variable name="copy-me">
       <Header>
           <Meta />
       </Header>
       <Body>
           <Document>
               <Preceding-1 />
               <Preceding-2 />
               <Make-Toute-Seul-1 />
               <Make-Toute-Seul-2 />
               <Make-Toute-Seul-3 />
               <Following-1 />
               <Following-2 />
           </Document>
       </Body>
   </xsl:variable>
<xsl:template match="/">
       <xsl:apply-templates select="$copy-me/*"/>
   </xsl:template>
<xsl:template match="Body">
       <xsl:copy>
           <xsl:apply-templates select="*[Make-Toute-Seul-1]" >
<xsl:with-param name="seul" select="*/Make-Toute-Seul-1" tunnel="yes" />
           </xsl:apply-templates>
           <xsl:apply-templates select="*[Make-Toute-Seul-2]" >
<xsl:with-param name="seul" select="*/Make-Toute-Seul-2" tunnel="yes" />
           </xsl:apply-templates>
           <xsl:apply-templates select="*[Make-Toute-Seul-3]" >
<xsl:with-param name="seul" select="*/Make-Toute-Seul-3" tunnel="yes" />
           </xsl:apply-templates>
       </xsl:copy>
   </xsl:template>
<xsl:template match="Document">
       <xsl:param name="seul"  tunnel="yes"/>
       <xsl:copy>
<xsl:copy-of select="$seul/preceding-sibling::*[not(self::Make-Toute-Seul-1 | self::Make-Toute-Seul-2 | self::Make-Toute-Seul-3)]" />
           <xsl:copy-of select="$seul" />
<xsl:copy-of select="$seul/following-sibling::*[not(self::Make-Toute-Seul-1 | self::Make-Toute-Seul-2 | self::Make-Toute-Seul-3)]" />
       </xsl:copy>
       </xsl:template>
<xsl:template match="* | @*">
       <xsl:copy>
           <xsl:apply-templates select="node() | @*" />
       </xsl:copy>
   </xsl:template>
</xsl:stylesheet>




Thanks for any help,

Cheers,

Abel

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--