Home > Enterprise >  XSLT Copy all nodes and only the last occurrence of a specific repeating node
XSLT Copy all nodes and only the last occurrence of a specific repeating node

Time:11-19

I'm looking to write something in XSLT 1.0 that achieves the following:

Input XML:

<parent>
    <header>
        <value1>1</value1>
        <value2>2</value2>
    </header>

    <repeating>
        <repeat>
            <rvalue1>1</rvalue1>
            <rvalue2>2</rvalue2>
        </repeat>
        <repeat>
            <rvalue1>3</rvalue1>
            <rvalue2>4</rvalue2>
        </repeat>
        <repeat>
            <rvalue1>5</rvalue1>
            <rvalue2>6</rvalue2>
        </repeat>
    </repeating>
</parent>

Output XML:

<parent>
    <header>
        <value1>1</value1>
        <value2>2</value2>
    </header>

    <repeating>
        <repeat>
            <rvalue1>5</rvalue1>
            <rvalue2>6</rvalue2>
        </repeat>
    </repeating>
</parent>

The that I want to copy is always the last one in the list. Any help on how to do this would be great. Thank you!

I tried using an identity template with a separate template match including something with last(), but couldn't get the result I wanted.

CodePudding user response:

Try it this way:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="repeating">
    <xsl:copy>
        <xsl:apply-templates select="repeat[last()]"/>
    </xsl:copy>
</xsl:template>
 
</xsl:stylesheet>

CodePudding user response:

You could also use

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

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

  <xsl:template match="repeating/repeat[not(position() = last())]"/>

</xsl:stylesheet>
  • Related