代码之家  ›  专栏  ›  技术社区  ›  pegasus

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

  •  1
  • pegasus  · 技术社区  · 7 年前

    我正在编写一个样式表来“规范化”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 属性的值为 可选择的 ?

    1 回复  |  直到 7 年前
        1
  •  0
  •   pegasus    7 年前

    @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不会复制属性并按要求的顺序保留它们,即使它是由 @* 条款因此,这确实以最少的努力满足了我目前的需求,即使它不是一个通用的解决方案(我实际上并不需要)。