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