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

Re: copy single node once from one location to another

Subject: Re: copy single node once from one location to another
From: Peter Davis <pdavis152@xxxxxxxxx>
Date: Fri, 6 Sep 2002 15:25:31 -0700
xsl apply template once
On Friday 06 September 2002 14:46, Thomas Olausson wrote:
> I'd like to write a XSLT that moves the data_text to the corresponding
> index of "a", expressed in data_nr. In the above case, /mydoc/a[2]

Define a key to look up the <specials> element corresponding to a specific 
<data_nr> value.  Later, you can pass a number to the key() function to get 
the corresponding <specials>, and then you can get the <data_text> element as 
a child of that.

<xsl:key name="specials" match="specials" use="data_nr"/>

You want to copy everything verbatim except for a few special cases, so define 
a basic identity template.  It will copy each element and its attributes, and 
it will apply-templates to its children.  You can define other templates to 
match specific elements that will override this one.

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

Define a template to handle <a> specially.  You want to copy <a>, its 
attributes, and its children just like for the normal identity template, but 
you also want to copy the <data_text> from the corresponding <specials> 
element.  The correct <specials> element is found by counting the number of 
<a> elements that come before the current one, and using that as the value 
for the proper <data_nr> (see the <xsl:key> element above).

It might be more efficient to use the position() function here, but to do that 
you'd have to make a special template to copy <mydoc> and only copy the <a> 
children.  That's because the plain <xsl:apply-templates> in the identity 
template will select *all* children (node()s actually) of <mydoc>, including 
whitespace-only text nodes and any other non-<a> elements.  Those extra nodes 
will mess up the position() function.

<xsl:template match="a">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates/>
    <xsl:apply-templates select="key('specials',
      count(preceding-sibling::a) + 1)/data_text"/>
  </xsl:copy>
</xsl:template>

Now, define a special template to copy <data_text>, but rename it to <data>.

<xsl:template match="data_text">
  <data>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates/>
  </data>
</xsl:template>

That's all untested, but hopefully it'll get you on the right track.

-- 
Peter Davis

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.