删除空元素和属性

时间:2017-01-31 14:04:04

标签: xslt

我有一个下面传入的XML请求,我想删除空节点,如“altname”

传入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>

我在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>

它没有按预期工作。

我需要以下XML输出:

所需的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="ID" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
         <saml2:AttributeValue>5345435345</saml2:AttributeValue>
      </saml2:Attribute>      
   </saml2:AttributeStatement>
</saml2:Assertion>

请让我知道如何做到这一点。

1 个答案:

答案 0 :(得分:1)

您使用身份模板是正确的 只是过滤掉你不想要的节点就可以得到你想要的结果。

因此,只需忽略具有空saml2:AttributeValue/text()的节点 - 具有简单空模板的节点就足够了:

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

所以使用这个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" 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>

<强>结果:

<?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>