Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
gho6
Participant
12,333


  • Introduction:-




As an XML developer, you may encounter situations where you need to filter XML data to select only nodes that do not contain certain content. For example, you might have a large XML document with multiple elements, but you only want to select elements that do not contain a certain character, such as a period. In this blog post, I will explore how to use XSLT to filter XML data and select nodes that do not contain certain content.

 


  • General Description:-




XSLT is a powerful language for transforming XML data. In this case, we will use XSLT to filter XML data and select nodes that do not contain certain content. The XSLT code consists of two templates, one for the root element and one for each row element. The first template matches the root element and copies it to the output. The second template matches each row element and applies a test to select only those elements that do not contain certain content.


I share one XML input file, requirement, code, and output with you in this example.

 

Input XML File:-

 
<?xml version="1.0"?>
<root>
<row>
<ID>1</ID>
<Name>John Doe</Name>
<Email>jdoe@example.com</Email>
<HourlyRate>15</HourlyRate>
<salary>4800</salary>
<OT>200</OT>
</row>
<row>
<ID>2</ID>
<Name>Jane Smith</Name>
<Email>janesmith@example.com</Email>
<HourlyRate>20</HourlyRate>
<salary>4567.50</salary>
<OT>200.20</OT>
</row>
<row>
<ID>3</ID>
<Name>Bob Johnson</Name>
<Email>bjohnson@example.com</Email>
<HourlyRate>25.50</HourlyRate>
<salary>3000</salary>
<OT>150</OT>
</row>
<row>
<ID>4</ID>
<Name>Ram Signh</Name>
<Email>ram99@example.com</Email>
<HourlyRate>25.50</HourlyRate>
<salary>3200</salary>
<OT>145.6</OT>
</row>
</root>

I take 5 employee data that have email and pay component details.

our requirement is only to keep that employee who has only HourlyRate value decimal if other field values are decimal remove that employee through our interface.

as per the requirement, I make one XSLT mapping which sends the output as per requirement.

Here is the XSLT code:-
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="row"/>
</xsl:copy>
</xsl:template>

<xsl:template match="row">
<xsl:if test="not(.//*[contains(text(),'.')) and not(self::HourlyRate)]">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

Code description :-

 

The code provided filters an XML document by selecting only the rows that contain a period, except for the HourlyRate element. Here's how the code works:

  1. The xsl:output element specifies the output format of the transformed XML.

  2. The xsl:template element with match="/root" matches the root element of the XML document and copies it to the output.

  3. The xsl:apply-templates element with select="row" applies the templates to all row elements in the XML document.

  4. The xsl:template element with match="row" matches each row element and checks the conditions in the xsl:if element.
    .


5. The second template matches each row element and applies a test to select only those elements that do not contain a period character (.) in any of their descendant nodes. The xsl:if element checks whether the test returns true or false. If it returns true, the xsl:copy-of element copies the entire row element to the output.
  <xsl:if test="not(.//*[contains(text(), '.')) and not(self::HourlyRate)])">
<xsl:copy-of select="."/>
</xsl:if>

This is an if statement in XSLT, which is used to control the flow of the transformation. The test attribute specifies the condition that must be true for the if statement to be executed.

In this case, the test attribute has two conditions that must both be true in order for the if statement to execute. The first condition is not(.//*[contains(text(), '.')]), which means "if there is no element anywhere in the current row that contains a period (.)". The not() function negates the result of the contains() function, so the overall condition is true only if there is no period in any element.

The second condition is not(self::HourlyRate), which means "if the current element is not a HourlyRate element". The self:: axis selects the current node, and the condition is true only if the current node is not a HourlyRate element.

If both conditions are true, then the if statement is executed. In this case, the statement simply copies the current row element to the output document using the xsl:copy-of instruction.

 

Output:-
<?xml version="1.0"?>
<root>
<row>
<ID>1</ID>
<Name>John Doe</Name>
<Email>jdoe@example.com</Email>
<HourlyRate>15</HourlyRate>
<salary>4800</salary>
<OT>200</OT>
</row>
<row>
<ID>3</ID>
<Name>Bob Johnson</Name>
<Email>bjohnson@example.com</Email>
<HourlyRate>25.50</HourlyRate>
<salary>3000</salary>
<OT>150</OT>
</row>
</root>

as per our requirement, using that XSLT mapping we get this output file where remove all row tag which contain "."  except HourlyRate tag value.

if you want those remove employee data also we can write this XSLT different way.

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

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/root">
<xsl:copy>
<xsl:apply-templates select="row"/>
</xsl:copy>
</xsl:template>

<xsl:template match="row">
<xsl:if test="(.//*[(contains(text(), '.')) and not(self::HourlyRate)])">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

using that code we can get those employee who have decimal data except HourlyRate Tag value.

using that XSLT code we  the output file file.

output file:-

 
<?xml version="1.0"?>
<root>
<row>
<ID>2</ID>
<Name>Jane Smith</Name>
<Email>janesmith@example.com</Email>
<HourlyRate>20</HourlyRate>
<salary>4567.50</salary>
<OT>200.20</OT>
</row>
<row>
<ID>4</ID>
<Name>Ram Signh</Name>
<Email>ram99@example.com</Email>
<HourlyRate>25.50</HourlyRate>
<salary>3200</salary>
<OT>145.6</OT>
</row>
</root>

This way we can get both data. i use in the real scenario.

 


 

I used this in CPI for one scenario.

In this scenario, I use one sequential multicast and send the data by filtering through XSLT mapping using code 1 , and in branch 2 we filter the data using code 2.



Conclusion:-


XSLT provides a powerful mechanism for filtering XML data. The example code we looked at demonstrates how to remove elements from an XML document that don't meet certain conditions. With XSLT, you can customize the transformation of XML documents to fit your specific needs. By leveraging the power of XSLT, you can efficiently transform XML documents into the format you require.

Note:-


I write this XSLT mapping based on the example. as per your requirement you can modify this code.

In this code we except only HourlyRate tag if your requirements with more tag then you can modify it accordingly.

If you like the blog and it's useful for you kindly share this.
Labels in this area