on 05-28-2021 7:31 PM
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
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
User | Count |
---|---|
74 | |
10 | |
8 | |
7 | |
6 | |
5 | |
5 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.