Home > Blockchain >  XSLT 2.0: Remove nodes from input XML based on condition
XSLT 2.0: Remove nodes from input XML based on condition

Time:10-06

I have an XML which might contain more than one employment_information nodes. I need to select the one which has child field assignment_class as 'GA'. Other employment_information nodes should be discarded. Also, if there is only one employment_information node, then it should be passed as it is.

Input XML:

<?xml version="1.0" encoding="utf-8"?>
<queryCompoundEmployeeResponse>
   <CompoundEmployee>
      <Person>
         <StartDate>2012-02-01</StartDate>
         <EndDate>2019-02-28</EndDate>
         <action>NO CHANGE</action>             
         <employment_information>
            <action>NO CHANGE</action>
            <assignment_class>ST</assignment_class>
         </employment_information>
         <employment_information>
            <action>NO CHANGE</action>
            <assignment_class>GA</assignment_class>
         </employment_information>
      </Person>
</CompoundEmployee>
</queryCompoundEmployeeResponse>

Expected Output:

<?xml version="1.0" encoding="UTF-8"?>
<queryCompoundEmployeeResponse>
   <CompoundEmployee>
      <Person>
         <StartDate>2012-02-01</StartDate>
         <EndDate>2019-02-28</EndDate>
         <action>NO CHANGE</action>
         <employment_information>
            <action>NO CHANGE</action>
            <assignment_class>GA</assignment_class>
         </employment_information>
      </Person>
   </CompoundEmployee>
</queryCompoundEmployeeResponse>

After referring some online posts, I am partially able to achieve this using below XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="//Person/employment_information[assignment_class!='GA']"/>
</xsl:stylesheet>

But I need to enhance this XSLT to finally have following logic:

  1. Count employment_information
  2. if Count is greater than 1, then select the employment_information with assignment_class as 'GA' along with other nodes in the input.
  3. Otherwise(i.e. if count is 0 or 1) copy input to output as it is.

Any help is appreciated. Thanks!

CodePudding user response:

If I read this correctly, here is one way you could look at it:

<xsl:stylesheet version="2.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="employment_information[assignment_class!='GA' and count(../employment_information) gt 1]"/>

</xsl:stylesheet>
  • Related