Ergosum
Ergosum

Reputation: 23

How to remove a complete node with XSLT based on the the value of one of his children

I am trying to filter out unwanted data from an XML file. I have the following XML:

<Client>
    <Address>
    </Address>
    <Documents>
        <Invoice>
            <Document></Document>
            <No>9999<No>
            <Content>H4s==</Content>
        </Invoice>
        <Invoice>
            <Document>
                <File>
                    <Code>THIS IS THE ONE<Code>
                    <Name>
                        <value locale="en">Invoice for January</value>
                    </Name>
                </File>
            </Document>
            <No>7777</No>
            <Content>H4sIAA1XyDQA=</Content>
        </Invoice>
    </Documents>
</Client>

And I don't want to have in the result all the <Invoice> where the <Document> tag is empty.

So in a sense the result would look like:

<Client>
    <Address>
    </Address>
    <Documents>
        <Invoice>
            <Document>
                <File>
                    <Code>THIS IS THE ONE<Code>
                    <Name>
                        <value locale="en">Invoice for January</value>
                    </Name>
                </File>
            </Document>
            <No>7777</No>
            <Content>H4sIAA1XyDQA=</Content>
        </Invoice>
    </Documents>
</Client>

Thanks,

Upvotes: 2

Views: 175

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52888

You would do this by overriding an identity template.

This XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="Invoice[not(Document/node())]"/>

</xsl:stylesheet>

Applied against your XML input (fixed to be well-formed):

<Client>
  <Address>
  </Address>
  <Documents>
    <Invoice>
      <Document></Document>
      <No>9999</No>
        <Content>H4s==</Content>
    </Invoice>
    <Invoice>
      <Document>
        <File>
          <Code>THIS IS THE ONE</Code>
            <Name>
              <value locale="en">Invoice for January</value>
            </Name>
        </File>
      </Document>
      <No>7777</No>
      <Content>H4sIAA1XyDQA=</Content>
    </Invoice>
  </Documents>
</Client>

Produces the following output:

<Client>
   <Address/>
   <Documents>
      <Invoice>
         <Document>
            <File>
               <Code>THIS IS THE ONE</Code>
               <Name>
                  <value locale="en">Invoice for January</value>
               </Name>
            </File>
         </Document>
         <No>7777</No>
         <Content>H4sIAA1XyDQA=</Content>
      </Invoice>
   </Documents>
</Client>

Upvotes: 2

Related Questions