I have an XML text document that looks like this:
<corpus>
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg type="not_foo">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus ultrices consequat facilisis.
Suspendisse a odio<note>foo note</note> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note>foo note</note> purus. Praesent
aliquam viverra tellus in condimentum.</seg>
</text>
</deposition>
<deposition>
<deposition-title>Elementum arcu non</deposition-title>
<text>
<seg type="foo">Curabitur pulvinar leo eget. Orci varius
natoque penatibus et magnis dis<note>foo note</note> montes,
nascetur ridiculus mus.</seg>
<seg type="not_foo">Morbi vehicula dolor bibendum enim mollis lobortis.
Nulla rutrum vel diam vel posuere. Aliquam pellentesque
malesuada elit sed tempor.</seg>
</text>
</deposition>
</corpus>
I am adding footnote numbers to it in preparation to print, doing some preprocess using XSL 3.0 on Saxon. The target output adds <footnote/>
plus increment number on two conditions, seg[@type='foo'] | note
. The numbers reset to zero for each deposition
. The result should look like this:
<corpus>
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg type="not_foo">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus ultrices consequat facilisis.
Suspendisse a odio<note>some note</note><footnote>1</footnote> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note>some note</note><footnote>2</footnote> purus. Praesent
aliquam viverra tellus in condimentum.</seg><footnote>3</footnote>
</text>
</deposition>
<deposition>
<deposition-title>Elementum arcu non</deposition-title>
<text>
<seg type="foo">Curabitur pulvinar leo eget. Orci varius
natoque penatibus et magnis dis<note>some note</note><footnote>1</footnote> montes,
nascetur ridiculus mus.</seg><footnote>2</footnote>
<seg type="not_foo">Morbi vehicula dolor bibendum enim mollis lobortis.
Nulla rutrum vel diam vel posuere. Aliquam pellentesque
malesuada elit sed tempor.</seg></seg><footnote>3</footnote>
</text>
</deposition>
</corpus>
I am using the following to copy and insert the <footnote>
with number:
<xsl:template match="seg[@type='foo'] | note">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy><footnote><xsl:number count="seg[@type='foo'] | note" from="deposition" format="1" level="any"/></footnote>
</xsl:template>
However, the result is not what I expected. It seems this template, in terms of assigning numbers, is treating the seg
element first, and then anything inside the seg
second? Like layers? In the case of the first deposition
it results in this new XML:
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg>Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus ultrices consequat facilisis.
Suspendisse a odio<note>some note</note><footnote>2</footnote> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note>some note</note><footnote>3</footnote> purus. Praesent
aliquam viverra tellus in condimentum.</seg><footnote>1</footnote>
</text>
</deposition>
This means the footnotes are not in 'real' (or 'printable') order.
Not sure what is causing this. Thanks for any assistance.
I have taken a different approach, it uses a first transformation step to add empty footnote
elements and a second transformation step to number these using xsl:number
:
<?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"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="xs math map array"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="add-footnotes" on-no-match="shallow-copy"/>
<xsl:variable name="footnotes">
<!-- populating variable by pushing the global context item's child node through the mode named 'add-footnotes' -->
<xsl:apply-templates mode="add-footnotes"/>
</xsl:variable>
<xsl:template match="seg[@type = 'foo'] | note" mode="add-footnotes">
<!-- delegating copying of the element to the identity transformation -->
<xsl:next-match/>
<footnote/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$footnotes/node()"/>
</xsl:template>
<xsl:template match="footnote">
<xsl:copy>
<xsl:number level="any" from="deposition"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Sample at http://xsltfiddle.liberty-development.net/eiQZDbe/1
I don't think you'll be able to do this with xsl:number
.
The only way I can think of really is to count the preceding seg
/note
, add 1 (for self), and add any descendant note
.
Preceding is not very efficient though so hopefully I'm overlooking something and you'll get a better answer.
Example...
XML Input (added an additional note
for testing)
<corpus>
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg type="not_foo">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus ultrices consequat facilisis.
Suspendisse a odio<note>foo note</note> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note>foo note</note> purus. Praesent
aliquam viverra tellus<note>another note</note> in condimentum.</seg>
</text>
</deposition>
<deposition>
<deposition-title>Elementum arcu non</deposition-title>
<text>
<seg type="foo">Curabitur pulvinar leo eget. Orci varius
natoque penatibus et magnis dis<note>foo note</note> montes,
nascetur ridiculus mus.</seg>
<seg type="not_foo">Morbi vehicula dolor bibendum enim mollis lobortis.
Nulla rutrum vel diam vel posuere. Aliquam pellentesque
malesuada elit sed tempor.</seg>
</text>
</deposition>
</corpus>
XSLT 2.0 (this is also valid 1.0)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="seg[@type='foo']|note">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:variable name="dep" select="generate-id(ancestor::deposition)"/>
<footnote>
<xsl:value-of
select="count((preceding::seg[@type='foo']|preceding::note)[generate-id(ancestor::deposition)=$dep]) + 1 + count(.//note)"/>
</footnote>
</xsl:template>
</xsl:stylesheet>
Output
<corpus>
<deposition>
<deposition-title>Praesent vitae</deposition-title>
<text>
<seg type="not_foo">Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Vivamus ultrices consequat facilisis.
Suspendisse a odio<note>foo note</note>
<footnote>1</footnote> in lobortis. Aenean
non dui scelerisque, rutrum est at, cursus sem.</seg>
<seg type="foo">Ut pharetra bibendum ipsum, portitor
velit pharetra quis. Aeneano<note>foo note</note>
<footnote>2</footnote> purus. Praesent
aliquam viverra tellus<note>another note</note>
<footnote>3</footnote> in condimentum.</seg>
<footnote>4</footnote>
</text>
</deposition>
<deposition>
<deposition-title>Elementum arcu non</deposition-title>
<text>
<seg type="foo">Curabitur pulvinar leo eget. Orci varius
natoque penatibus et magnis dis<note>foo note</note>
<footnote>1</footnote> montes,
nascetur ridiculus mus.</seg>
<footnote>2</footnote>
<seg type="not_foo">Morbi vehicula dolor bibendum enim mollis lobortis.
Nulla rutrum vel diam vel posuere. Aliquam pellentesque
malesuada elit sed tempor.</seg>
</text>
</deposition>
</corpus>