Reputation: 417
I have a hierachy of posten-elements within a root element, something like
<gliederung>
<posten id=".." order="1">
<posten id=".." order"1">
<posten id=".." order"1">
...
</posten>
<posten id="AB" order"2">
...
</posten>
...
</posten>
<posten id=".." order"2">
...
</posten>
<posten id="XY" order"3">
...
</posten>
....
</gliederung>
Each posten has a unique id and a order attribute. Now I need to move element with id "XY" before element with id "AB" and change the order attribute of the moved element "XY" to "1.5".
I managed to move the element with the following script:
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="posten[@id='AB']">
<xsl:copy-of select="../posten[@id='XY']"/>
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="posten[@id='XY']"/>
But how to combine the move with changing the order attribute value to "1.5?
I'm missing something obvious I guess ...
Upvotes: 1
Views: 672
Reputation: 122394
Instead of copy-of
, use a template
<!-- almost-identity template, that does not apply templates to the
posten[@id='XY'] -->
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()[not(self::posten[@id='XY'])]|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="posten[@id='AB']">
<!-- apply templates to the XY posten - this will copy it using the
"identity" template above but will allow the specific template
for its order attr to fire -->
<xsl:apply-templates select="../posten[@id='XY']"/>
<xsl:call-template name="identity"/>
</xsl:template>
<!-- fix up the order value for XY -->
<xsl:template match="posten[@id='XY']/@order">
<xsl:attribute name="order">1.5</xsl:attribute>
</xsl:template>
If you're not sure exactly where the XY posten will be relative to the AB one (i.e. will it always be ../posten[@id='XY']
or might it sometimes be ../../
), then you could define a
<xsl:key name="postenById" match="posten" use="@id" />
and then replace the <xsl:apply-templates select="../posten[@id='XY']"/>
with
<xsl:apply-templates select="key('postenById', 'XY')"/>
Upvotes: 1