Toya
Toya

Reputation: 37

Remove Empty Nodes with XSL Based on a Specific Attribute

I have XSL that removes empty tags for an entire xml, however I want to remove empty tags for one node section when the attribute is "DELETE". Any assistance is appreciated. See example XML and XSL below.

XML Example:

<?xml version="1.0" encoding="UTF-8"?>
<UGNX xmlns="http://www.ems-ag.de/xmlschemas/test/UGNX.XSD">
    <Items Action="UPDATE">
        <PartyCode>TSTeb</PartyCode>
        <CatalogCode>TestCatalog</CatalogCode>
        <Item Action="ADDORUPDATE">
            <ItemCode>TST12345</ItemCode>
            <ItemType>REGULAR</ItemType>
            <ItemState>V</ItemState>
            <AttributeAttachments Action="UPDATE">
                <AttributeAttachment Action="DELETE">
                    <AttributeUID>
                        <PartyCode>TSTeb</PartyCode>    
                        <AttributeClassificationCode>TestSchema
                        </AttributeClassificationCode>
                        <AttributeCode>TestAttribute</AttributeCode>
                   </AttributeUID>
                   <AttributeValues Action="REPLACE">
                     <Value Action="ADDORUPDATE">
                        <Order>0</Order>
                        <Enumeration/>
                     </Value>
                   </AttributeValues>
               </AttributeAttachment>
            <AttributeAttachment Action="ADDORUPDATE">
                <AttributeUID>
                    <PartyCode>TSTeb</PartyCode>
                    <AttributeClassificationCode>TestSchema
                    </AttributeClassificationCode>
                    <AttributeCode>TestAttribute2</AttributeCode>
                </AttributeUID>
                <AttributeValues Action="REPLACE">
                    <Value Action="ADDORUPDATE">
                        <Order>0</Order>
                        <Translatable/>
                    </Value>
                </AttributeValues>
            </AttributeAttachment>
          </AttributeAttachments>
         </Item>
       </Items>
     </UGNX>

Expected Result below. The empty node is removed when the AttributeAttachment "Action" attribute is "DELETE".

<?xml version="1.0" encoding="UTF-8"?>
<UGNX xmlns="http://www.ems-ag.de/xmlschemas/test/UGNX.XSD">
    <Items Action="UPDATE">
        <PartyCode>TSTeb</PartyCode>
        <CatalogCode>TestCatalog</CatalogCode>
        <Item Action="ADDORUPDATE">
            <ItemCode>TST12345</ItemCode>
            <ItemType>REGULAR</ItemType>
            <ItemState>V</ItemState>
            <AttributeAttachments Action="UPDATE">
                <AttributeAttachment Action="DELETE">
                    <AttributeUID>
                        <PartyCode>TSTeb</PartyCode>    
                        <AttributeClassificationCode>TestSchema
                        </AttributeClassificationCode>
                        <AttributeCode>TestAttribute</AttributeCode>
                   </AttributeUID>
                   <AttributeValues Action="REPLACE">
                     <Value Action="ADDORUPDATE">
                        <Order>0</Order>
                     </Value>
                   </AttributeValues>
               </AttributeAttachment>
            <AttributeAttachment Action="ADDORUPDATE">
                <AttributeUID>
                    <PartyCode>TSTeb</PartyCode>
                    <AttributeClassificationCode>TestSchema
                    </AttributeClassificationCode>
                    <AttributeCode>TestAttribute2</AttributeCode>
                </AttributeUID>
                <AttributeValues Action="REPLACE">
                    <Value Action="ADDORUPDATE">
                        <Order>0</Order>
                        <Translatable/>
                    </Value>
                </AttributeValues>
            </AttributeAttachment>
          </AttributeAttachments>
         </Item>
       </Items>
     </UGNX>

Current XSL:

<?xml version="1.0" encoding="UTF-8"?>

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

    <xsl:template match="*">
    <xsl:if test=". != '' or ./@* != ''">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:if>
    </xsl:template>

   <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="." />
        </xsl:attribute>
   </xsl:template>
       <xsl:template match="text() | comment() | processing-instruction()">
       <xsl:copy />
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Views: 177

Answers (1)

Tim C
Tim C

Reputation: 70598

You should move your current logic for checking for "empty" elements out of the template matching "*" and instead have a separate template that matches empty elements, and ignores them.....

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="@* | node()" />
    </xsl:element>
</xsl:template>

<xsl:template match="*[@Action='DELETE']//*[not(* or @* or normalize-space())]" />

Here I am defining empty as having no child elements, no attributes, and no non-space text.

Upvotes: 1

Related Questions