1

I am in need to move XML element to the repective place based on the attribute value. The element <m:footnote> should be moved from <m:endnote> to the respective place when the attribute value of id is matching.

Sample XML:

<m:chapter xmlns:m="http://www.w3.org/1998/Math/MathML">
  <m:front>
    <m:p>This is <m:footnote id="1"/>para</m:p>
  </m:front>
  <m:body>
    <m:p>This is <m:footnote id="2"/>para</m:p>
    <m:p>This is <m:footnote id="3"/>para</m:p>
    <m:p>This is <m:footnote id="4"/>para</m:p>
  </m:body>
  <m:endnote>
    <m:footnote id="1">This is footnote 1</m:footnote>
    <m:footnote id="2">This is footnote 2</m:footnote>
    <m:footnote id="3">This is footnote 3</m:footnote>
    <m:footnote id="4">This is footnote 4</m:footnote>
  </m:endnote>
</m:chapter>

Output required:

<?xml version='1.0' encoding='UTF-8' ?>
<m:chapter xmlns:m="http://www.w3.org/1998/Math/MathML">
<m:front>
<m:p>This is <m:footnote id="1">This is footnote 1</m:footnote>para</m:p>
</m:front>
<m:body>
<m:p>This is <m:footnote id="2">This is footnote 2</m:footnote>para</m:p>
<m:p>This is <m:footnote id="3">This is footnote 3</m:footnote>para</m:p>
<m:p>This is <m:footnote id="4">This is footnote 4</m:footnote>>para</m:p>
</m:body>
</m:chapter>

XSLT tried:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML" exclude-result-prefixes="m">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="m:chapter">
<xsl:copy>
<xsl:apply-templates/>
<xsl:for-each select="child::*/descendant::m:footnote">
<xsl:choose>
<xsl:when test="not(parent::m:endnote)">
<xsl:if test="string(self::m:footnote/@id) = string('ancestor::m:chapter/m:endnote/m:footnote/@id')">
<xsl:copy-of select="m:chapter/m:endnote/m:footnote"/>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="m:endnote"></xsl:template>
</xsl:stylesheet>

1 Answer 1

3

This should do it:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:m="http://www.w3.org/1998/Math/MathML" exclude-result-prefixes="m">
  <xsl:output method="xml" encoding="UTF-8" indent="no"/>
  <xsl:key name="kEndnote" match="m:endnote/m:footnote" use="@id"/>
  <xsl:key name="kFootnoteRef" match="m:p/m:footnote" use="@id"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="m:footnote">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="key('kEndnote', @id)"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="m:endnote[not(m:footnote[not(key('kFootnoteRef', @id))])]" />
  <xsl:template match="m:endnote/m:footnote[key('kFootnoteRef', @id)]" />
</xsl:stylesheet>

When run on your sample input, this produces:

<m:chapter xmlns:m="http://www.w3.org/1998/Math/MathML">
  <m:front>
    <m:p>This is <m:footnote id="1">This is footnote 1</m:footnote>para</m:p>
  </m:front>
  <m:body>
    <m:p>This is <m:footnote id="2">This is footnote 2</m:footnote>para</m:p>
    <m:p>This is <m:footnote id="3">This is footnote 3</m:footnote>para</m:p>
    <m:p>This is <m:footnote id="4">This is footnote 4</m:footnote>para</m:p>
  </m:body>

</m:chapter>

When run on your sample input with the 2nd and 3rd <m:p> removed, this produces:

<m:chapter xmlns:m="http://www.w3.org/1998/Math/MathML">
  <m:front>
    <m:p>This is <m:footnote id="1">This is footnote 1</m:footnote>para</m:p>
  </m:front>
  <m:body>
    <m:p>This is <m:footnote id="4">This is footnote 4</m:footnote>para</m:p>
  </m:body>
  <m:endnote>

    <m:footnote id="2">This is footnote 2</m:footnote>
    <m:footnote id="3">This is footnote 3</m:footnote>

  </m:endnote>
</m:chapter>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer, another thing is, if attribute value of id is not matching then '<m:endnote>' element with the <m:footnote> whose id is not matching should be retained.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.