XSLT报错:如何匹配div任意顺序的class属性避免创建错误
解决XSLT属性生成顺序错误的方案
这个错误的核心原因很明确:XSLT有硬性规则——所有属性节点必须在元素的任何子节点(包括文本、其他元素、注释)之前创建,和原HTML里的属性顺序完全没关系。你之前的模板应该是先处理了div的子节点,或者先输出了其他内容,再去生成class属性,才触发了这个报错。
下面给你几种靠谱的解决办法:
1. 规范模板执行顺序(最常用)
写一个匹配div的模板,先处理所有属性(包括class),再处理子节点:
<xsl:template match="div"> <xsl:copy> <!-- 先处理所有属性,不管原顺序,XSLT会按规则生成 --> <xsl:apply-templates select="@*"/> <!-- 再处理div内部的子节点 --> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template>
如果需要单独修改class属性,比如给它加个前缀,直接写匹配div/@class的模板就行,只要保证属性模板在子节点之前被调用:
<xsl:template match="div/@class"> <xsl:attribute name="class"> <xsl:text>custom-</xsl:text> <xsl:value-of select="."/> </xsl:attribute> </xsl:template>
2. 手动构建元素时调整顺序
如果你是手动输出div元素,别先写子节点再补属性,这是典型错误写法:
<!-- 错误:先写子节点再加属性 --> <div> <span>内容</span> <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute> </div>
正确的写法是先把所有属性写完,再写子节点:
<!-- 正确:先加属性,再加子节点 --> <div> <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute> <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute> <span>内容</span> </div>
3. 用属性集合批量处理
如果需要给多个元素复用相同的属性规则,可以用<xsl:attribute-set>提前定义,创建元素时直接引用,属性会自动在子节点之前生成:
<xsl:attribute-set name="div-default-attrs"> <xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute> <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute> </xsl:attribute-set> <xsl:template match="div"> <xsl:element name="div" use-attribute-sets="div-default-attrs"> <xsl:apply-templates select="node()"/> </xsl:element> </xsl:template>
核心原则记住:不管原HTML里属性排第几,只要在XSLT里让属性的生成操作全部早于子节点的输出/处理,就不会再碰到这个错误。
内容的提问来源于stack exchange,提问作者adam78
相关产品推荐
相关产品推荐

