Reputation: 47
I need to move the following-siblings that are just after the current element inside the current element. I do not understand why what I am doing is not working, could you please help me understand why?
I have this XML input:
<book>
<prelim>
<introd></introd>
<introd></introd>
<bibl></bibl>
<bibl></bibl>
</prelim>
I need to have this output:
<book>
<prelim>
<introd></introd>
<introd>
<bibl></bibl>
<bibl></bibl>
</introd>
</prelim>
It tried this :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="*"><xsl:element name="{local-name()}"><xsl:apply-templates/></xsl:element>
</xsl:template>
<xsl:template match="introd">
<introd>
<xsl:apply-templates/>
<xsl:variable name="i"><xsl:value-of select="following-sibling::bibl/position()"/></xsl:variable>
<xsl:if test="following-sibling::*[$i]=following-sibling::bibl[$i]">
<xsl:apply-templates select="following-sibling::bibl[following-sibling::*[$i]=following-sibling::bibl[$1]]"></xsl:apply-templates>
</xsl:if>
</introd>
</xsl:template>
</xsl:stylesheet>
Thank you! Maria
Upvotes: 0
Views: 81
Reputation: 167571
I would suggest to match on prelim
and then use xsl:for-each-group select="*" group-starting-with="introd"
:
<xsl:template match="prelim">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="introd">
<xsl:copy>
<xsl:apply-templates select="node(), tail(current-group())"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
The rest can be handled by the identity transformation, declarable with xsl:mode
in XSLT 3 (https://xsltfiddle.liberty-development.net/naZYrpT) or spelled out as a template in XSLT 2. tail
is not available in XSLT 2 but you can use subsequence(current-group(), 2)
instead.
Upvotes: 1
Reputation: 47
Thank you, Martin Honnen. I resolved this the following way:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="*"><xsl:element name="{local-name()}"><xsl:apply-templates/></xsl:element></xsl:template>
<xsl:template match="introd">
<introd><xsl:apply-templates></xsl:apply-templates>
<xsl:if test="following-sibling::*[1]=following-sibling::bibl[1]"><xsl:for-each-group select="parent::prelim/bibl" group-starting-with="introd"><xsl:for-each select="current-group()">
<xsl:copy-of select="."/>
</xsl:for-each></xsl:for-each-group></xsl:if></introd>
</xsl:template>
<xsl:template match="bibl"></xsl:template>
</xsl:stylesheet>
Upvotes: 0