Home > OS >  XSLT to Retain elements based on a child node value
XSLT to Retain elements based on a child node value

Time:08-04

I am new to XSLT and need some help. I am trying to search but unable to succeed.

Can anyone help me achieve the below using XSLT? Basically, i need to retain all the elements within a parent node only if any of the child node (Flag) has 'Change' in it. The child node can be deep inside at level 4 or 5 as well. Not sure if it would be a complex XSLT

XSLT standards: 1.0, 2.0, or 3.0 any one is fine

Input XML:

<SampleMessages>
    <SampleMessage>
        <Field1>ABCD1</Field1>
        <Field2>XYZ1</Field2>
        <Tree1>
            <Flag>Change</Flag>
            <Field3>SomeData1</Field3>
            <Field4>SomeData2</Field4>
            <Tree2>
                <Flag>No Change</Flag>
                <Field3>SomeData1</Field3>
                <Field4>SomeData2</Field4>
            </Tree2>
        </Tree1>
    </SampleMessage>
    <SampleMessage>
        <Field1>ABCD2</Field1>
        <Field2>XYZ2</Field2>
        <Tree1>
            <Flag>No Change</Flag>
            <Field3>SomeData3</Field3>
            <Field4>SomeData4</Field4>
        </Tree1>
    </SampleMessage>
    <SampleMessage>
        <Field1>ABCD3</Field1>
        <Field2>XYZ3</Field2>
        <Tree1>
            <Flag>No Change</Flag>
            <Field3>SomeData5</Field3>
            <Field4>SomeData6</Field4>
            <Tree2>
                <Flag>No Change</Flag>
                <Field3>SomeData5</Field3>
                <Field4>SomeData6</Field4>
            </Tree2>
        </Tree1>
    </SampleMessage>
    <SampleMessage>
        <Field1>ABCD4</Field1>
        <Field2>XYZ4</Field2>
        <Tree1>
            <Flag>No Change</Flag>
            <Field3>SomeData7</Field3>
            <Field4>SomeData8</Field4>
            <Tree2>
                <Flag>Change</Flag>
                <Field3>SomeData9</Field3>
                <Field4>SomeData10</Field4>
            </Tree2>
        </Tree1>
    </SampleMessage>
</SampleMessages>

Desired Output:

  <SampleMessages>
    <SampleMessage>
        <Field1>ABCD1</Field1>
        <Field2>XYZ1</Field2>
        <Tree1>
            <Flag>Change</Flag>
            <Field3>SomeData1</Field3>
            <Field4>SomeData2</Field4>
            <Tree2>
                <Flag>No Change</Flag>
                <Field3>SomeData1</Field3>
                <Field4>SomeData2</Field4>
            </Tree2>
        </Tree1>
    </SampleMessage>
    <SampleMessage>
        <Field1>ABCD4</Field1>
        <Field2>XYZ4</Field2>
        <Tree1>
            <Flag>No Change</Flag>
            <Field3>SomeData7</Field3>
            <Field4>SomeData8</Field4>
            <Tree2>
                <Flag>Change</Flag>
                <Field3>SomeData9</Field3>
                <Field4>SomeData10</Field4>
            </Tree2>
        </Tree1>
    </SampleMessage>
</SampleMessages>

My Try I am sure it will be more complex than this :) As it isnt working..

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <!--Identity template to copy all content by default-->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>


    <xsl:template match="//Flag[not('Change')]"/>

</xsl:stylesheet>

CodePudding user response:

Please try the following solution.

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="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="SampleMessage[not(*//Flag='Change')]"/>
</xsl:stylesheet>
  • Related