XSLT:xsl:function不起作用

时间:2009-07-14 18:27:14

标签: xslt

以下适用于我:

<xsl:variable name="core" select="document('CoreMain_v1.4.0.xsd')" />
<xsl:variable name="AcRec" select="document('AcademicRecord_v1.3.0.xsd')" />

<xsl:template match="xs:element">       
  <xsl:variable name="prefix" select="substring-before(@type, ':')" />
  <xsl:variable name="name" select="substring-after(@type, ':')" />

  <xsl:choose>
    <xsl:when test="$prefix = 'AcRec'">             
      <xsl:apply-templates select="$AcRec//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>
    <xsl:when test="$prefix = 'core'">              
      <xsl:apply-templates select="$core//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>             
  </xsl:choose>
</xsl:template>

但是我使用相同的逻辑来处理基于前缀的当前或其他文档中的元素的查找,在样式表中的许多地方匹配节点名称。因此,在将样式表版本更改为2.0之后,我尝试了:

<xsl:template match="xs:element">
  <xsl:value-of select="my:lookup(@type)" />
</xsl:template>

<xsl:function name="my:lookup">
  <xsl:param name="attribute" />

  <!-- parse the attribute for the prefix & name values -->
  <xsl:variable name="prefix" select="substring-before($attribute, ':')" />
  <xsl:variable name="name" select="substring-after($attribute, ':')" />

  <!-- Switch statement based on the prefix value -->
  <xsl:choose>
    <xsl:when test="$prefix = 'AcRec'">             
      <xsl:apply-templates select="$AcRec//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>
    <xsl:when test="$prefix = 'core'">              
      <xsl:apply-templates select="$core//*[@name=$name]">
        <xsl:with-param name="prefix" select="$prefix" />
      </xsl:apply-templates>                
    </xsl:when>             
  </xsl:choose> 
</xsl:function>

在我的阅读中,我只找到了返回文本的函数示例 - 没有调用模板。我的印象是xsl:function应该总是返回text / output ...

经过更多调查后,它正在进入my:lookup函数,变量(前缀和名称)将被填充。所以它确实输入了xsl:choose语句,并且在测试时命中了相应的。问题似乎与apply-templates有关 - value-of显示子值; copy-of也是如此,我认为这很奇怪(输出中是否应该包含xml元素声明?)。如果在模板声明中工作的代码被移动到xsl:function?

,为什么会有区别?

1 个答案:

答案 0 :(得分:2)

我做了任何严肃的XSLT已经有一段时间了,但是IIRC你的问题不在函数中,而是在你的模板中:

<xsl:template match="xs:element">
  <xsl:value-of select="my:lookup(@type)" />
</xsl:template>

value-of语句不会内联函数返回的结果树。相反,它会尝试将结果树缩减为某种字符串,并将其内联。这就是你看到孩子的价值而不是元素本身的原因。

要内联函数返回的结果树,您需要使用一些模板将结果树复制到位。

因此,您的主模板需要更改为:

<xsl:template match="xs:element">
  <xsl:apply-templates select="my:lookup(@type)" />
</xsl:template>

你需要一些模板来进行递归调用。快速谷歌找到a good discussion of the identity template应该做你需要的。

(请原谅任何语法错误,正如我所说,已经有一段时间......)