xsl-list
[Top] [All Lists]

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

2007-04-25 08:14:12
Perhaps something like this:

<xsl:for-each select="Document/*[starts-with(name(), 'Make-Toute-Seul')]"/>
  <Document>
    <xsl:copy-of select="../* except ."/>
  </Document>
</xsl:for-each>

Michael Kay
http://www.saxonica.com/ 

-----Original Message-----
From: Abel Braaksma [mailto:abel(_dot_)online(_at_)xs4all(_dot_)nl] 
Sent: 25 April 2007 15:53
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Copying parent nodes with different selection 
of their content

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>
--~--



--~------------------------------------------------------------------
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>
--~--