Skip to Content
Technical Articles
Author's profile photo Alexandre Rezende

How to remove all empty tags from an XML in SAP PI… It’s Simple!

Hi Guys!

Today I will share a little tip that can be very useful in some cases, how to remove all empty tags from an XML.

In some cases, you need to remove tags that are empty (Ex. <tag> </tag> or <tag/>), and creating this rule in all fields by graphical mapping would be a lot of work.

The tip is to use the code below in your message mapping:

Source code:

public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException {
	try {
		InputStream inputstream = transformationInput.getInputPayload().getInputStream();
		OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();

		byte[] b = new byte[inputstream.available()];
		inputstream.read(b);
		String encoding ="UTF-8";
		String inputXML=new String(b);

		inputXML = inputXML.replaceAll("<\\s*[\\w:]+?\\s*\\/>", "");
		inputXML = inputXML.replaceAll("<\\s*[\\w:]+>(<\\/?\\w+>)*<\\/\\s*[\\w:]+>", "");
	
		outputstream.write(inputXML.getBytes(encoding));

	} catch (Exception exception) {
		getTrace().addDebugMessage(exception.getMessage());
		throw new StreamTransformationException(exception.toString());
	}
}

 

Test:

Below is an example of the mapping performed, where the field <complemento2\> was removed:

 

Another Solution (XSLT)

It’s possibile use another solution, a XSLT mapping, below the source code of an XSLT shared by our colleague @Evgeniy Kolmakov.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>
</xsl:stylesheet>

I recommend testing both solutions to see which one best applies to your project.

Notes:

  1. You can use this code and roles in graphical mapping
  2. The java code is executed after the graphical mapping.
  3. If you want to remove only one field, apply the role below in your field:

I hope I helped you with this little tip… 😀

 

 

Assigned tags

      16 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Carlos Rodrigo
      Carlos Rodrigo

      Nice blog post!

      Author's profile photo Alexandre Rezende
      Alexandre Rezende
      Blog Post Author

      Carlos Rodrigo , Tks for your feedback! 🙂

      Author's profile photo anitra carol
      anitra carol

      Thanks for this great post!

      SAP PI/PO (Process Integration/Process Orchestration) is a tool that allows you to integrate solutions. It makes it easy to synchronize data between different systems. Let’s say you are using the SAP ERP system, and you wish to integrate with the CRM system.

      Author's profile photo Daniel Graversen
      Daniel Graversen

      Hi Alexander,

      Good you got the problem solved.

      I would be very careful about adding Java Mapping code into a message mapping. It may be really difficult for someone else to see that it is going on. I get that it is easy to set up and compile than creating a manage a java mapping.

      I would also recommend using a SAX parser that is a little more stable than manipulating XML Strings via regex.

      Daniel

      Author's profile photo Alexandre Rezende
      Alexandre Rezende
      Blog Post Author

      Hi Daniel Graversen ,

      Thank you for you reply. Soon, I will publish the code with this improvement. Would using the DOM be a good solution?

      Author's profile photo Carlos Rodrigo
      Carlos Rodrigo

      ​ DOM is not a perfect way to maintain the performance in during the integration, this occurs because DOM allocate the XML content in memory, SAX is faster them DOM because the XML is partial allocated in memory

      Author's profile photo Andrzej Filusz
      Andrzej Filusz

      Hi Alexandre

      One small comment related to the code below:

      byte[] b = new byte[inputstream.available()];

      Have you read about available() method?

      https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available()

      According to that documentation:  It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream.

      BTW, I recommend you to specify the charset when you construct a new String based on an array of bytes.

      Regards,

      Andrzej

       

      Author's profile photo Evgeniy Kolmakov
      Evgeniy Kolmakov

      Hi Alexandre!

      I used to avoid java mappings whenever it's possible,so, I prefer to use simple XSL transformation for such cases:

      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:output indent="yes"/>
          <xsl:strip-space elements="*"/>
          
          <xsl:template match="node()|@*">
              <xsl:copy>
                  <xsl:apply-templates select="node()|@*"/>
              </xsl:copy>
          </xsl:template>
          
          <xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>
          
      </xsl:stylesheet>

      Regards, Evgeniy.

      Author's profile photo Alexandre Rezende
      Alexandre Rezende
      Blog Post Author

      Hi @Evgeniy Kolmakov ,

      I'ts possible use the XSLT to remove  empty fields, but my intention is to show the easiest solution to be implemented. I believe that this solution would be "easier", as it is enough to copy and paste the code of the mapping message.

      Both Java and XSLT work, just choose which one suits you best. 🙂

      Author's profile photo Carlos Rodrigo
      Carlos Rodrigo

      But XSLT is better then use a JAVA inside the mapping. XSLT will be always faster them java during the XML transformation

      Author's profile photo Anupam Ghosh
      Anupam Ghosh

      Hi Carlos,

      After moving to single stack all mappings need to be converted to java code before execution. This is done internally by SAP PI. Thus XSLT code cannot be faster than java mapping code for the same algorithm.

      Please correct me in case I am wrong.

       

      Regards

      Anupam

      Author's profile photo Alexandre Rezende
      Alexandre Rezende
      Blog Post Author

      @Evgeniy Kolmakov , I shared this code in this post and I quote you, ok?

      Author's profile photo Evgeniy Kolmakov
      Evgeniy Kolmakov

      Hi Alexandre!

      Sure, it's ok.

      Regards, Evgeniy.

      Author's profile photo Anupam Ghosh
      Anupam Ghosh

      good article.

      Author's profile photo Alexandre Rezende
      Alexandre Rezende
      Blog Post Author

      Thank you Anupam Ghosh !!!

      Author's profile photo antonio lopez
      antonio lopez

      Hi. it´s a really good article... I have a issue related with that...I am working with simple transformation to generate XML from internal tables, but when I try to get the XML through the DEBUG I realized that there´s someting wrong... in some TAGS of XML there are some blank spaces... so I am trying to delete thoses blank Spaces, but i can´t get where those comes from...

      I am newbie in Abap Wolrd. Hope anyone can give a had how to solve it..

      https://answers.sap.com/questions/13475605/how-to-delete-blank-space-in-xml-tag-simple-transf.html