user5458829
user5458829

Reputation: 163

Removing empty element and attribute

I have an below incoming XML request i want to remove empty node like "altname"

Incoming XML:

<saml2:Assertion Version="2.0" ID="SAML-727af5f8-6bd0-45f8-b9c0-c95e3c5da9f5" IssueInstant="2016-01-31T13:27:28Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:Issuer>ssodp</saml2:Issuer>    
   <saml2:AttributeStatement>      
      <saml2:Attribute Name="altname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
         <saml2:AttributeValue/>
      </saml2:Attribute>
      <saml2:Attribute Name="ID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
         <saml2:AttributeValue>5345435345</saml2:AttributeValue>
      </saml2:Attribute>      
   </saml2:AttributeStatement>
</saml2:Assertion>

I have written below XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[ not(descendant-or-self::node()[normalize-space()]) and 

not(descendant-or-self::*/@*[normalize-space()] and not(count(descendant-or-self::*/@*) = count(descendant-or-self::*/@xsi:nil)) ) ]">
        <xsl:if test="local-name(.) = 'Envelope' or local-name(.) = 'Body' or local-name(.) = 'payload'">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

It's not working as expected.

I need the below XML output:

Desired XML Output:

<saml2:Assertion Version="2.0" ID="SAML-727af5f8-6bd0-45f8-b9c0-c95e3c5da9f5" IssueInstant="2016-01-31T13:27:28Z" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:Issuer>ssodp</saml2:Issuer>    
   <saml2:AttributeStatement>
      <saml2:Attribute Name="ID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
         <saml2:AttributeValue>5345435345</saml2:AttributeValue>
      </saml2:Attribute>      
   </saml2:AttributeStatement>
</saml2:Assertion>

Please let me know how to do this.

Upvotes: 0

Views: 625

Answers (1)

zx485
zx485

Reputation: 29022

You were right in using the identity template.
Just filtering out the nodes you don't want will give you your desired result.

So just ignoring the nodes which have an empty saml2:AttributeValue/text()-node with a simple empty template is sufficient:

<xsl:template match="saml2:Attribute[normalize-space(saml2:AttributeValue/text()) = '']" />

So use this XSLT - which has only minor modifications compared to yours:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">

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

    <!-- filter out the nodes with an empty 'saml2:AttributeValue' child -->
    <xsl:template match="saml2:Attribute[normalize-space(saml2:AttributeValue/text()) = '']" />

</xsl:stylesheet>

Result:

<?xml version="1.0"?>
<saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="SAML-727af5f8-6bd0-45f8-b9c0-c95e3c5da9f5" IssueInstant="2016-01-31T13:27:28Z">
    <saml2:Issuer>ssodp</saml2:Issuer>    
    <saml2:AttributeStatement>      
        <saml2:Attribute Name="ID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
            <saml2:AttributeValue>5345435345</saml2:AttributeValue>
        </saml2:Attribute>
    </saml2:AttributeStatement>
</saml2:Assertion>

Upvotes: 1

Related Questions