xpath-functions不标识外部Java类

时间:2012-07-25 13:47:41

标签: xml xslt

每当我尝试使用函数node-name()时,以下XSLT转换都会显示错误。

  

错误:E [Saxon6.5.5] URI http://www.w3.org/2005/xpath-functions无法识别外部Java类

<xsl:stylesheet version="1.1" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions">
<!--
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-->        

    <xsl:output method="text" />
    <xsl:variable name="in" select="/"/>
    <xsl:variable name="filter" select="document('elementsToBeLeftIn.xml')"/>

    <xsl:template match="/">
        <xsl:apply-templates select="*">
            <xsl:with-param name="f" select="$filter/*"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="*">
        <xsl:param name="f"/>
        <xsl:choose>
            <xsl:when test="$f/*">
                <xsl:copy-of select="fn:node-name()"/>

                <!--
                <xsl:for-each select="*[fn:node-name(.) = $f/*/fn:node-name(.)]">
                    <xsl:apply-templates select=".">
                        <xsl:with-param name="f" select="f/*[fn:node-name() = current()/fn:node-name()]"/>
                    </xsl:apply-templates>
                </xsl:for-each>
                -->
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>    

谢谢大卫。 这就是我真正想要的工作(它是递归的)。使用name()我仍然会收到错误*Unexpected tocken [<function>] in path expression*

之后
<xsl:stylesheet version="1.1" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions">
<!--
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-->        

    <xsl:output method="text" />
    <xsl:variable name="in" select="/"/>
    <xsl:variable name="filter" select="document('elementsToBeLeftIn.xml')"/>

    <xsl:template match="/">
        <xsl:apply-templates select="*">
            <xsl:with-param name="f" select="$filter/*"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="*">
        <xsl:param name="f"/>
        <xsl:choose>
            <xsl:when test="$f/*">
                <xsl:for-each select="*[name() = $f/*/name()]">
                    <xsl:apply-templates select=".">
                        <xsl:with-param name="f" select="f/*[name() = current()/name()]"/>
                    </xsl:apply-templates>
                </xsl:for-each>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>    

2 个答案:

答案 0 :(得分:0)

即使在XSLT2中,您也不需要为node-name()等标准函数添加前缀。但是您使用的是撒克逊语6,它是XSLT1,因此您不能为函数添加前缀,否则它们将永远不会被识别。 (XPath 1标准函数不在命名空间中)

只需使用select="name()"

但是我认为你的代码不会像你期望的那样工作(但你没有说出你想要它做什么),但它只会将模板应用于一个元素(顶级文档元素)作为模板永远不会递归申请。

如果过滤器测试为真,<xsl:copy-of select="name()"会输出该元素的名称,没有标记(因此结果不会很好地形成xml)。

如果过滤器测试为false,则将包括其所有子项的整个文档元素复制到输出中,不再进行进一步处理。

$f/*/name()

在XPath2中是合法的,但在XPath 1中不合法,其中使用/的路径表达式可能只使用不以返回字符串的函数结束的节点。不确定你想要做什么,所以不能立即替换。

 current()/name()

可以写成

 name(current())
在XPath 1中

但是既然你正在使用saxon java实现,为什么不简单地使用saxon 9代替saxon 6并从xslt引擎中进行十多年的进一步开发中获益呢?

答案 1 :(得分:0)

Saxon 6.5.5是一个XSLT 1.0引擎。命名空间http://www.w3.org/2005/xpath-functions适用于XPATH 2.0,XSLT 2.0和XSLT 3.0。 XSLT 1.0无法识别此命名空间。这就是你收到错误的原因。

没有XSLT 1.0等效于http://www.w3.org/2005/xpath-functions。只需调用没有前缀的函数。