当元素具有特定值时从元素中删除属性

时间:2017-11-06 18:37:15

标签: xslt xsd xslt-2.0

我正在编写一个样式表来“规范化”XML模式,以便更容易地比较它们。它将按名称排序顶级元素,按固定顺序对订单属性进行排序等。这是我迄今为止的属性:

<xsl:template match="xsd:attribute">
    <xsl:copy>      
        <xsl:copy-of select="@name"/>
        <xsl:copy-of select="@type"/>
        <xsl:copy-of select="@ref"/>
        <xsl:copy-of select="@use"/>
        <xsl:copy-of select="@default"/>
        <xsl:apply-templates select="@*">
            <xsl:sort select="name()"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

现在我想删除多余的属性。例如,应删除use = "optional",因为无论如何optional是默认值。

所以我的问题是:当值为use时,为了删除optional属性,最简单的方法是增强上面的代码?

1 个答案:

答案 0 :(得分:0)

@JohnBollinger和@MartinHonnen正确地指出@*条件将插入所有属性,甚至是上面选择的属性。因此必须改进条件。还指出,根据规范,不能确保属性的顺序。他们 被订购的事实只是我的处理器(Saxon9-HE)如何工作的工件。我对此很好。这是我到达的解决方案:

<xsl:template match="xsd:attribute">
    <xsl:copy>
        <xsl:copy-of select="@name" />
        <xsl:copy-of select="@type" />
        <xsl:copy-of select="@ref" />
        <xsl:copy-of select="@use[string() != 'optional']" />
        <xsl:copy-of select="@default" />
        <xsl:apply-templates select="@*[name(.) != 'use']">
            <xsl:sort select="name()" />
        </xsl:apply-templates>
        <xsl:apply-templates select="node()" />
    </xsl:copy>
</xsl:template>

我没有将其他属性名称添加到@*上的负数过滤器,因为Saxon不会复制属性并将它们保留在所需的顺序中,即使它被@*子句重新插入也是如此。所以这确实以最少的努力满足了我目前的需求,即使它不是通用的解决方案(我实际上并不需要)。