【问题标题】:XSLT - Adding attribute to element in separate templates?XSLT - 在单独的模板中向元素添加属性?
【发布时间】:2013-08-12 01:47:19
【问题描述】:

我正在尝试将属性添加到另一个元素的 '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”元素是动态创建的,因此必须按照我的理论建议,通过添加来自另一个模板的属性来完成,但显然这是不正确的。这可以做到吗?感谢您的宝贵时间。

【问题讨论】:

    标签: xslt attributes


    【解决方案1】:

    这里发生的情况是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 属性使用属性值模板使其更简洁,但这不是必需的。

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

    【讨论】:

      【解决方案2】:

      ... 或 @style 使用 AVT ...

      <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>  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-24
        • 2013-08-25
        • 2011-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多