Reputation: 815
In this example text-based XML below, using XSL 3.0/Saxon, I'd like to move any footnote
that immediately follows a seg
element into the seg
element, just before the closing </seg>
and after whatever text() and children may be inside the seg
.
My experiments at http://xsltfiddle.liberty-development.net/pPgCcon and http://xsltfiddle.liberty-development.net/pPgCcon/1
(a) are inelegant, and
(b) fail to capture the right following::
element
The is the source XML:
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg n="seg1" type="not_foo">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus<note2 n="abc">another note 2</note2><appnote>a</appnote> ultrices consequat facilisis.
Suspendisse a odio<note n="def">foo note</note><footnote>1</footnote> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg n="seg2" type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note n="ghi">foo note</note><footnote>2</footnote> purus. Praesent
aliquam viverra tellus<note n="jkl">another note</note><footnote>3</footnote> in condimentum.</seg><footnote>4</footnote>
</text>
<deposition>
This is the target XML - note how <footnote>4</footnote>
has moved from outside the preceding seg
into the seg
element after all the text()
.
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg n="seg1" type="not_foo">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus<note2 n="abc">another note 2</note2><appnote>a</appnote> ultrices consequat facilisis.
Suspendisse a odio<note n="def">foo note</note><footnote>1</footnote> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg n="seg2" type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note n="ghi">foo note</note><footnote>2</footnote> purus. Praesent
aliquam viverra tellus<note n="jkl">another note</note><footnote>3</footnote> in condimentum.<footnote>4</footnote></seg>
</text>
<deposition>
XSL 3.0 at http://xsltfiddle.liberty-development.net/pPgCcon:
<?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="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml"/>
<xsl:template match="seg">
<seg>
<xsl:for-each select="./attribute() | text() | *">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:copy-of select="./following::*[1]"/>
</seg>
</xsl:template>
</xsl:stylesheet>
Another version at http://xsltfiddle.liberty-development.net/pPgCcon/1:
<?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="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml"/>
<xsl:template match="seg">
<seg>
<xsl:for-each select="./attribute() | text() | *">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:copy-of select="./following::node()[name() = footnote]"/>
</seg>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 29
Reputation: 167471
I think you need two templates, one for the seg
to copy the following sibling footnote
, the other to prevent the identity template to copy the footnote in its input position:
<xsl:template match="seg">
<seg>
<xsl:apply-templates select="@* | node()"/>
<xsl:copy-of select="following-sibling::node()[1][self::footnote]"/>
</seg>
</xsl:template>
<xsl:template match="deposition/text//footnote[preceding-sibling::node()[1][self::seg]]"/>
http://xsltfiddle.liberty-development.net/pPgCcon/3
Upvotes: 2