XPath的函数可用():为什么它的结果随样式表中的位置而变化,如何用它来保护新的

时间:2013-12-12 13:31:09

标签: xslt xpath saxon

在Java XSLT扩展(对于Saxon 9.1.0.8)中,我编写了一个函数,首先在它上面创建一个新对象和调用实例方法(在XSLT 1.0样式表中)。以下是展示相同问题的缩短版本:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://www.acrolinx.com" xmlns:saxon="http://saxon.sf.net/" version="1.1" extension-element-prefixes="saxon mt" xmlns:mt="http://www.jclark.com/xt/java/com.acrolinx.xsltextensions.MTExporter">
 <xsl:variable name="exportMediaFile-available" select="function-available('mt:exportMediaFile')"/>
 <xsl:variable name="mt" select="mt:new('http', 'localhost', 8031, 'uID', 'hDB', 'o/eT', 'Mt')"/>

<xsl:template match="/">
  <xsl:message>exportMediaFile <xsl:value-of select="function-available('mt:exportMediaFile')"/></xsl:message>
  <xsl:element name="mtf">
    <xsl:apply-templates select="a:actif/a:data/a:entry"/>
  </xsl:element>
  <xsl:message>finalizeExport <xsl:value-of select="function-available('mt:finalizeExport')"/></xsl:message>
</xsl:template>

<xsl:template match="a:entry">
  <xsl:element name="conceptGrp">
    <xsl:apply-templates select="a:value"/>
  </xsl:element>
</xsl:template>

<xsl:template match="a:value">
  <xsl:if test="@field != ''">
    <xsl:call-template name="descrip">
      <xsl:with-param name="type" select="@field"/>
      <xsl:with-param name="content" select="saxon:evaluate('node()')"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template name="descrip">
  <xsl:param name="type"/>
  <xsl:param name="content"/>
  <xsl:element name="descrip">
    <xsl:attribute name="type">
      <xsl:value-of select="$type"/>
    </xsl:attribute>
    <xsl:choose>
  <xsl:when test="$type = 'imageURL' and $exportMediaFile-available">
    <xsl:message>exportMediaFile <xsl:value-of select="function-available('mt:exportMediaFile')"/></xsl:message>
    <xsl:value-of select="mt:exportMediaFile($mt, $content)"/>
  </xsl:when>
  <xsl:otherwise>
    <xsl:copy-of select="$content"/>
  </xsl:otherwise>
    </xsl:choose>
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

问题:

  • 我想用function-available()来保护来电,但它似乎会返回不同的结果,具体取决于样式表中的位置(= function-available()不是函数本身)被调用 事实证明,使用saxon:evaluate('node()') 更改 function-available的行为:没有(即node())它正在按预期工作,而{{1} } {},saxon:evaluate()调用在function-available()模板中返回false。是什么原因(因为这两个似乎与我无关)?

  • 有没有办法用descrip保护构造函数调用?我无法在顶层使用function-available()。如果我使用xsl:if

  • 实例化变量mt

(其中jo只是普通Java对象的命名空间 - 为布局道歉,但文本仍然不可见),如果扩展不可用,它就可以工作。如果可用,我会收到以下错误:

<xsl:variable name="mt"><xsl:choose><xsl:when test="function-available('mt:new')"><xsl:value-of select="mt:new('http', 'localhost', 8031, 'uID', 'hDB', 'o/eT', 'Mt')"/></xsl:when><xsl:otherwise><xsl:value-of select="jo:new()"/></xsl:otherwise></xsl:choose></xsl:variable>

事实上已经发生了

    Cannot convert value class net.sf.saxon.value.TextFragmentValue of type document-node() to class com.acrolinx.xsltextensions.MTExporter

也许正在进行一些隐式演员表,因此它适用于<xsl:variable name="mt"> <xsl:value-of select="mt:new('http', 'localhost', 8031, 'uID', 'hDB', 'o/eT', 'Mt')"/> </xsl:variable> ,但不适用于嵌套select

1 个答案:

答案 0 :(得分:0)

我认为您需要显示一些特定的代码,这些代码会提供您无法解释的结果:如果代码没有达到预期效果,那么我们需要查看代码以了解您的期望错误的原因。理想情况下,给出一个完整的样式表:上下文(例如版本号,名称空间声明等)可能很重要。

在XSLT 2.0中,我建议在use-when属性中使用function-available(),以便在编译时屏蔽调用相关函数的代码。在xsl中使用它的麻烦:if是函数调用对编译器仍然可见,并且无法解决。 XSLT 1.0(以及向后兼容模式下的2.0)允许这样做,并且如果您实际评估函数调用,则只会出现错误。

消息“无法将text-node()类型的值类net.sf.saxon.value.TextFragmentValue转换为...”不是我通常希望看到的。它可能是一个Saxon bug,或者它可能只是对某些用户错误的相当差的诊断。无论哪种方式,我都希望看到你做了什么导致这条消息的细节。