如何在xsl:copy中的所有未选定属性上执行apply-templates?

时间:2012-09-07 02:48:46

标签: xslt apply-templates

假设我有以下XSLT:

<xsl:template match="property">
    <xsl:copy>
        <xsl:apply-templates select="@id"/>
        <xsl:apply-templates select="@name"/>
        <xsl:apply-templates select="@componentClassID"/>
    </xsl:copy>
  </xsl:template>

如何使用apply-templates语句结束副本,该语句选择以前的apply-templates语句中未指定的所有属性?

以下是否正确?

<xsl:apply-templates select="@*[name()!='id' and name()!='name' and name()!='componentClassID']"/>

2 个答案:

答案 0 :(得分:3)

  

以下是否正确?

<xsl:apply-templates select=
 "@*[name()!='id' and name()!='name' and name()!='componentClassID']"/>

是的,但似乎太长了。此外,建议永远不要使用!=运算符,因为当其中一个参数是节点集时,它的语义(行为)不直观。

当要排除许多属性名称时,我宁愿使用以下样式进行编写:

<xsl:apply-templates select=
 "@*[not(contains('+id+name+componentClassID+', concat('+', name(), '+')))]"/>

答案 1 :(得分:0)

在XSLT 2.0中,您当然可以使用

<xsl:apply-templates select="@* except (@id, @name, @class)"/>

您还可以将其缩减为单个apply-templates:

<xsl:apply-templates select="@id, @name, @class, @* except (@id, @name, @class)"/>

如果你对重复感到不舒服,你可以使用一种方法:

<xsl:apply-templates select="@*">
  <xsl:sort select="f:attOrder(.)"/>
</xsl:apply-templates>

<xsl:function name="f:attOrder" as="xs:integer">
  <xsl:param name="a" as="attribute()"/>
  <xsl:variable name="ix" select="index-of(("id", "name", "class"), local-name($a))"/>
  <xsl:sequence select="($ix, 1000)[1]"/>
</xsl:function>

或者(这个也适用于1.0)你可以使用模式:

<xsl:apply-templates select="@id"/>
<xsl:apply-templates select="@name"/>
<xsl:apply-templates select="@componentClassID"/>
<xsl:apply-templates select="@*" mode="remainder"/>

<xsl:template match="@id|@name|@componentClassID" mode="remainder"/>