Home > Back-end >  Conditionally remove a node in XML document using XSL stylesheet
Conditionally remove a node in XML document using XSL stylesheet

Time:03-11

I have this XML-document, and I want to remove the Pnlty-node and all its children if the value in Id is equal to 05295.

<Root>
    <GenericTag>
        <twSender>akds</twSender>
        <NetworkInfo>
            <twService>okooko</twService>
        </NetworkInfo>
    </GenericTag>
    <Payload>
        <Document xmlns="urn:iso:std:iso:11111:tech:xsd:DRAFT5semt.000.001.002">
            <SpcKtp>
                <Pnlty>
                    <PtyId>
                        <Id>
                            <Id>
                                <HalwId>
                                    <Id>05295</Id>
                                    <Issr>VPDK</Issr>
                                </HalwId>
                            </Id>
                        </Id>
                     </PtyId>
                  </Pnlty>
             </SpcKtp>
        </Document>
    </Payload>
 </Root>

The desired output would look like this:

<Root>
    <GenericTag>
        <twSender>akds</twSender>
        <NetworkInfo>
            <twService>okooko</twService>
        </NetworkInfo>
    </GenericTag>
    <Payload>
        <Document xmlns="urn:iso:std:iso:11111:tech:xsd:DRAFT5semt.000.001.002">
            <SpcKtp>
            </SpcKtp>
        </Document>
    </Payload>
 </Root>

I have tried with this XSL-stylesheet in XML-validator 3.1.0.1

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <!-- The identity transformation -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <!-- The empty template for what I want to NOT copy -->
    <xsl:template match = "Root/Payload/Document/SpcKtp/Pnlty/Id/Id/HalwId/Id= '05295'"/>
</xsl:stylesheet>

And it does not work.

I have played around with the empty template to try to figure out what might be the issue.

<xsl:template match = "Root/Payload/Document"/>

And this does NOT remove the node Document (and none of its children).

However, this line works differently:

<xsl:template match = "Root/Payload"/>

It removes the node Payload and all its children. That is, it does not copy it with the identity transformation.

So I figured that it could be a problem with the attribute in the node and I thus tried:

<xsl:template match = "Root/Payload/Document |@*"/>

and some variants of it, including hard coding the value of the xmlns attribute. Nothing. To me it seems as if the node Document is "blocking" the path where I can evaluate the condition. Pls correct me if I am wrong.

CodePudding user response:

You can't just ignore namespaces. In your path you need to write something like

match = "Root/Payload/d:Document/d:SpcKtp/d:Pnlty...."

and declare xmlns:d="urn:iso:std:iso:11111:tech:xsd:DRAFT5semt.000.001.002"

CodePudding user response:

I think you want

<!-- The empty template for what I want to NOT copy -->
<xsl:template match = "Root/Payload/iso:Document/iso:SpcKtp/iso:Pnlty[iso:Id/iso:Id/iso:HalwId/iso:Id= '05295']" xmlns:iso="urn:iso:std:iso:11111:tech:xsd:DRAFT5semt.000.001.002"/>
  • Related