XSLT - 在单独的模板中向元素添加属性?

时间:2013-08-10 03:23:45

标签: xslt attributes

我正在尝试将一个属性添加到另一个'xsl:element name =“div”'元素中 模板,'xsl:template match =“KTheme”'模板,但是我收到了一个XSLT错误,没有关于失败原因或失败原因的错误信息。有没有办法做到这一点?

基本上,当从'xsl:template name =“DisplayFrame”'模板执行'xsl:apply-templates /'行时,它会与'KTheme'元素匹配,并应将“style”属性添加到“div”元素:

<xsl:template match="Frame">
    <xsl:call-template name="DisplayFrame">
        <xsl:with-param name="FrameId" select="'frameHeader'" /> 
    </xsl:call-template>
</xsl:template>

<xsl:template name="DisplayFrame">
    <xsl:param name="FrameId" />

    <xsl:element name="div">
        <xsl:attribute name="id">
            <xsl:value-of select="$FrameId" />
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

下面的模板是“style”属性应添加到“div”元素的位置。这个模板是给我一个错误的模板,因为一旦我删除'xsl:attribute'元素,XSLT就会成功编译。

<xsl:template match="KTheme">
    <xsl:attribute name="style">
        <xsl:value-of select="." />
    </xsl:attribute>
</xsl:template>

示例XML文件:

<Document>
    <Frame>
        <KTheme>background-color: red;</KTheme>
    </Frame>
</Document>

实际上,'KTheme'元素是动态创建的,因此必须按照我的理论建议,通过添加另一个模板的属性来完成,但显然它是不正确的。可以这样做吗?谢谢你的时间。

2 个答案:

答案 0 :(得分:2)

这里发生的事情是KTheme之前和之后都有空白文本节点,并且在该属性之前将其添加到输出之前。在将非属性节点添加到父元素后,尝试向父元素添加属性是错误的。

为了更安全,我建议直接定位KTheme元素,然后处理其他任何内容。这应该可以解决您的问题:

  <xsl:template name="DisplayFrame">
    <xsl:param name="FrameId" />

    <div id="{$FrameId}">
      <xsl:apply-templates select="KTheme" />
      <xsl:apply-templates select="node()[not(self::KTheme)]" />
    </div>
  </xsl:template>

我还使用id属性的属性值模板使其更清洁,但这不是必需的。

作为旁注,将<xsl:strip-space elements="*"/>添加到XSLT的顶部以去除空白文本节点也可以防止出现此错误,但我仍然认为在您之前主动定位可能产生属性的任何内容更明智处理其他事情。在错误的时间意外添加属性可能会导致整个XSLT失败。

答案 1 :(得分:1)

...或AVT for @style ...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="@*|node()" name="ident">
 <xsl:copy>
   <xsl:apply-templates select="@*|node()" />
 </xsl:copy> 
</xsl:template>  

<xsl:template match="Frame">
  <div id="frameHeader" style="{KTheme}">
   <xsl:apply-templates select="node()[not(self::KTheme)]" />
  </div>  
</xsl:template>  

</xsl:stylesheet>