Subject: Re: [xsl] copy single node once from one location to another From: Peter Davis <pdavis152@xxxxxxxxx> Date: Fri, 6 Sep 2002 15:25:31 -0700 |
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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] copy single node once from on, Thomas Olausson | Thread | Re: [xsl] copy single node once fro, Peter Davis |
[xsl] copy single node once from on, Thomas Olausson | Date | Re: [xsl] copy single node once fro, Peter Davis |
Month |