cancel
Showing results for 
Search instead for 
Did you mean: 

Remove XML node based on the condition of element value using xslt mapping

0 Kudos

Hi all,

I have below xml input structure.

<?xml version="1.0" encoding="UTF-8"?>

<record>

<data>

<person>

<id>123</id>

<job_info>

<event>R</event>

<end_date>9999-12-31</end_date>

</job_info>

<job_info>

<event>5</event>

<end_date>9991-12-31</end_date>

</job_info>

<job_info>

<event>26</event>

<end_date>9999-07-31</end_date>

</job_info>

<job_info>

<event>H</event>

<end_date>9999-11-31</end_date>

</job_info>

</person>

</data>

<data>

<person>

<id>122</id>

<job_info>

<event>5</event>

<end_date>9999-12-31</end_date>

</job_info>

<job_info>

<event>H</event>

<end_date>9990-12-31</end_date>

</job_info>

</person>

</data>

</record>

******************************************************************************************

Requirement is to remove the job_info tag if end_date is not equals to '9999-12-31' and event not in(R,H,6). So the output will be

******************************************************************************************

<?xml version="1.0" encoding="UTF-8"?>

<record>

<data>

<person>

<id>123</id>

<job_info>

<event>R</event>

<end_date>9999-12-31</end_date>

</job_info>

</person>

</data>

<data>

<person>

<id>122</id>

</person>

</data>

</record>

**************************************************************************

Can you please tell me how can we achieve it by xslt mapping.

Any leads would be highly appreciated.

Thanks,

Divya

MortenWittrock
Active Contributor
0 Kudos

Hi Divya

Given your rule, shouldn't event 5 with end date 9999-12-31 be in the output? It's not in your sample output.

Or maybe try phrasing it without the negations, i.e. what to you want to keep in, instead of what you want to remove.

Regards,

Morten

0 Kudos

Hi Morten,

I want job_info tag only if it has a value of "event" as 6 or H or R and the "end_date" should be '9999-12-31'.

Moreover I have multiple fields under the person tag. It is not only "id" and "job_info". Person tag is as below

<person>

<id>123</id>

<name>divya</name>

<city>satna</city>

<job_info>

***********

</job_info>

<job_info>

***********

</job_info>

<country>India</country>

<company>abc</company>

</person>

View Entire Topic
MortenWittrock
Active Contributor
0 Kudos

Hi Divya

This can be solved with a very short stylesheet, using the technique I described in this blog post. Here's the stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:mode on-no-match="shallow-copy" />
  <xsl:template match="job_info[not(end_date = '9999-12-31' and event = ('R', 'H', '6'))]" />
</xsl:stylesheet>

What it does, is copy everything from the input XML, except the job_info elements you don't want.

If you also want to remove data elements, that have no person/job_info children, you can add an additional template like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:mode on-no-match="shallow-copy" />
  <xsl:template match="job_info[not(end_date = '9999-12-31' and event = ('R', 'H', '6'))]" />
  <xsl:template match="data[not(person/job_info[end_date = '9999-12-31' and event = ('R', 'H', '6')])]" />
</xsl:stylesheet>

Regards,

Morten

P.S. It leaves some spare newlines in the output, that are most likely harmless, but if you want to remove them, the blog post describes how.

0 Kudos

Hi Morten,

I always found XSLT very complex and scary that is why I used to prefer graphical mapping always. But there are a lot of requirements that can not be accomplished using graphical mapping.

I got your blog so helpful and I want to see more if you have any channel on LinkedIn or youtube regarding XSLT mapping.

Well, the XSLT mapping you provided above is working as expected. But I want to ask, what if I want to remove "DATA" tag itself if the above condition is satisfied (job_info is not present in the "person" node). How will that work? I can think of below XSLT but it's not working.

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" />

<xsl:mode on-no-match="shallow-copy" />

<xsl:template match="job_info[not(end_date = '9999-12-31' and event = ('R', 'H', '6'))]" />

<xsl:template match="data/person[not(job_info)]" />

<xsl:template match="data[not(person)]" />

</xsl:stylesheet>

Thanks,

Divya

MortenWittrock
Active Contributor
0 Kudos

Hi pandeydivya82

I've updated the answer with an additional template, which does what you mention in your comment.

Since your question was answered, please keep in mind to accept the answer.

Regards,

Morten