jbrehr
jbrehr

Reputation: 815

Copy an element while moving 'following' element inside same element

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

Answers (1)

Martin Honnen
Martin Honnen

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

Related Questions