SAP CPI (Groovy): How to filter parent node based on grandchild node

718 views Asked by At

I'm using SAP CPI platform and I want to remove the parent node (payload) based on its grandchild nodes (localeId and translation). The input XML provided is like this:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <payload>
      <title>Doc1</title>
      <localizedTitle>
         <localeID>es</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
      <localizedTitle>
         <localeID>en</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
   </payload>
   <payload>
      <title>Doc3</title>
      <localizedTitle>
         <localeID>es</localeID>
         <translation>Type 3</translation>
      </localizedTitle>
      <localizedTitle>
         <localeID>en</localeID>
         <translation>Type 3</translation>
      </localizedTitle>
   </payload>
   <payload>
      <title>Doc4</title>
      <localizedTitle>
         <localeID>es</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
      <localizedTitle>
         <localeID>en</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
   </payload>
</root>

I want to remove the payload nodes that its localeId != "es" and translation!= "Type 1" using Groovy.

The result will be like this (only Doc1 and Doc4 are correct):

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <payload>
      <title>Doc1</title>
      <localizedTitle>
         <localeID>es</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
      <localizedTitle>
         <localeID>en</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
   </payload>
   <payload>
      <title>Doc4</title>
      <localizedTitle>
         <localeID>es</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
      <localizedTitle>
         <localeID>en</localeID>
         <translation>Type 1</translation>
      </localizedTitle>
   </payload>
</root>
1

There are 1 answers

2
Yitzhak Khabinsky On BEST ANSWER

Please try the following XSLT.

It is using a so called Identity Transform pattern.

Input XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <payload>
        <title>Doc1</title>
        <localizedTitle>
            <localeID>es</localeID>
            <translation>Type 1</translation>
        </localizedTitle>
        <localizedTitle>
            <localeID>en</localeID>
            <translation>Type 1</translation>
        </localizedTitle>
    </payload>
    <payload>
        <title>Doc3</title>
        <localizedTitle>
            <localeID>es</localeID>
            <translation>Type 3</translation>
        </localizedTitle>
        <localizedTitle>
            <localeID>en</localeID>
            <translation>Type 3</translation>
        </localizedTitle>
    </payload>
    <payload>
        <title>Doc4</title>
        <localizedTitle>
            <localeID>es</localeID>
            <translation>Type 1</translation>
        </localizedTitle>
        <localizedTitle>
            <localeID>en</localeID>
            <translation>Type 1</translation>
        </localizedTitle>
    </payload>
</root>

XSLT

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

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

    <xsl:template match="payload[localizedTitle/localeID!='es' and not(localizedTitle/translation=('Type 1','Type 2'))]"/>
</xsl:stylesheet>

Output XML

<?xml version='1.0' encoding='utf-8' ?>
<root>
  <payload>
    <title>Doc1</title>
    <localizedTitle>
      <localeID>es</localeID>
      <translation>Type 1</translation>
    </localizedTitle>
    <localizedTitle>
      <localeID>en</localeID>
      <translation>Type 1</translation>
    </localizedTitle>
  </payload>
  <payload>
    <title>Doc4</title>
    <localizedTitle>
      <localeID>es</localeID>
      <translation>Type 1</translation>
    </localizedTitle>
    <localizedTitle>
      <localeID>en</localeID>
      <translation>Type 1</translation>
    </localizedTitle>
  </payload>
</root>