0

my requirement is to consider last GS15 occurrence under HEADER/GS9 by removing other GS15 in it, if GS9 has only one GS15 occurrence or no GS15 then we can copy the GS9 segment as it is. If there is no GS9 in the input, we need to have rest of the data. my xslt is working if only one GS9 exist under HEADER. for multiple GS9 segments its giving me sequence error, Please have a look once.

Input:

<?xml version="1.0" encoding="UTF-8"?>
<HEADER>
    <SUBNODE>
        <FIELD1>001</FIELD1>
    </SUBNODE>
    <GS1>
        <FIELD1>12</FIELD1>
    </GS1>
    <GS9>
        <SUBN>
            <FIELD1>1</FIELD1>
        </SUBN>
        <GS11>
            <FIELD1>12</FIELD1>
        </GS11>
        <GS15>
            <GS16>
                <ATC>
                    <FIELD1>HE</FIELD1>
                </ATC>
            </GS16>
        </GS15>
        <GS15>
            <GS16>
                <ATC>
                    <FIELD1>123</FIELD1>
                </ATC>
            </GS16>
        </GS15>
    </GS9>
    <GS9>
        <SUBN>
            <FIELD1>1</FIELD1>
        </SUBN>
        <GS11>
            <FIELD1>12</FIELD1>
        </GS11>
        <GS15>
            <GS16>
                <ATC>
                    <FIELD1>245</FIELD1>
                </ATC>
            </GS16>
        </GS15>
        <GS15>
            <GS16>
                <ATC>
                    <FIELD1>456</FIELD1>
                </ATC>
            </GS16>
        </GS15>
    </GS9>
    <GS9>
        <SUBN>
            <FIELD1>1</FIELD1>
        </SUBN>
        <GS11>
            <FIELD1>12</FIELD1>
        </GS11>
    </GS9>
    <GS18>
        <FIELD1>4141</FIELD1>
    </GS18>
</HEADER>


Desired output:

<?xml version="1.0" encoding="UTF-8"?>
<HEADER>
    <SUBNODE>
        <FIELD1>001</FIELD1>
    </SUBNODE>
    <GS1>
        <FIELD1>12</FIELD1>
    </GS1>
    <GS9>
        <SUBN>
            <FIELD1>1</FIELD1>
        </SUBN>
        <GS11>
            <FIELD1>12</FIELD1>
        </GS11>
        <GS15>
            <GS16>
                <ATC>
                    <FIELD1>123</FIELD1>
                </ATC>
            </GS16>
        </GS15>
    </GS9>
    <GS9>
        <SUBN>
            <FIELD1>1</FIELD1>
        </SUBN>
        <GS11>
            <FIELD1>12</FIELD1>
        </GS11>
        <GS15>
            <GS16>
                <ATC>
                    <FIELD1>456</FIELD1>
                </ATC>
            </GS16>
        </GS15>
    </GS9>
    <GS9>
        <SUBN>
            <FIELD1>1</FIELD1>
        </SUBN>
        <GS11>
            <FIELD1>12</FIELD1>
        </GS11>
    </GS9>
    <GS18>
        <FIELD1>4141</FIELD1>
    </GS18>
</HEADER>

XSLT I used is below:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:key name="gs15key" match="GS15" use="generate-id()"/>
    <xsl:template match="/HEADER">
        <HEADER>
            <xsl:apply-templates select="node()"/>
        </HEADER>
    </xsl:template>
    <xsl:template match="GS15">
        <xsl:if test="generate-id() = generate-id(//GS15[last()])">
            <G_SG15>
                <xsl:apply-templates select="node()"/>
            </G_SG15>
        </xsl:if>
    </xsl:template>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

 
   
        
3
  • Change <xsl:if test="generate-id() = generate-id(//GS15[last()])"> to <xsl:if test="generate-id() = generate-id(parent::*/GS15[last()])"> Commented Dec 15, 2024 at 11:06
  • 1
    Just as a note, in XSLT 2 and later there is the is operator that checks node identity so any check you would use in XSLT 1 with generate-id you can simply write with the is operator e.g. . is ../GS15[last()] checks whether the context node . is the (same as the) last GS15 child of its parent. Commented Dec 15, 2024 at 13:37
  • noted Martin, thanks Commented Dec 17, 2024 at 11:48

1 Answer 1

0

Use an empty template for any non last GS15 child element of a GS9 parent plus the identity transformation

  <xsl:template match="GS9/GS15[position() != last()]"/>

  <xsl:mode on-no-match="shallow-copy"/>
Sign up to request clarification or add additional context in comments.

Comments

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.