Search code examples
xsltxml-nil

XSLT remove unwanted elements


I have XML

<getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <inquiryAbouts>
        <inquiryAbout>
            <code>Code</code>
            <nameKk>Something</nameKk>
            <nameRu>Something</nameRu>
            <documents xsi:nil="true"/>
        </inquiryAbout>
    </inquiryAbouts>
</getInquiryAboutListReturn>

And I want to process it with XSLT to copy all XML

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes" />
    <xsl:template match="/">
        <xsl:copy-of select="//getInquiryAboutListReturn/inquiryAbouts"/>
    </xsl:template>
</xsl:stylesheet>

How could I copy all XML without <documents xsi:nil="true"/> or without xsi:nil="true"?

Desired output XML

<getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <inquiryAbouts>
        <inquiryAbout>
            <code>Code</code>
            <nameKk>Something</nameKk>
            <nameRu>Something</nameRu>
        </inquiryAbout>
    </inquiryAbouts>
</getInquiryAboutListReturn>

Solution

  • This simple XSLT:

    <?xml version="1.0"?>
    <xsl:stylesheet 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      version="1.0">
    
      <xsl:output omit-xml-declaration="no" indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <!-- TEMPLATE #1 -->
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <!-- TEMPLATE #2 -->
      <xsl:template match="*[@xsi:nil = 'true']" />
    
    </xsl:stylesheet>
    

    ...when applied to the OP's source XML:

    <?xml version="1.0"?>
    <getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <inquiryAbouts>
        <inquiryAbout>
          <code>Code</code>
          <nameKk>Something</nameKk>
          <nameRu>Something</nameRu>
          <documents xsi:nil="true"/>
        </inquiryAbout>
      </inquiryAbouts>
    </getInquiryAboutListReturn>
    

    ...produces the expected result XML:

    <?xml version="1.0"?>
    <getInquiryAboutListReturn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <inquiryAbouts>
        <inquiryAbout>
          <code>Code</code>
          <nameKk>Something</nameKk>
          <nameRu>Something</nameRu>
        </inquiryAbout>
      </inquiryAbouts>
    </getInquiryAboutListReturn>
    

    EXPLANATION:

    1. The first template -- the Identity Template -- copies all nodes and attributes from the source XML document as-is.
    2. The second template, which matches all elements with the specified, namespaced attribute equalling "true", effectively removes those elements.