2

每当我尝试使用函数 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>    
4

2 回答 2

0

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

只需使用select="name()"

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

在过滤器测试为真的情况下,<xsl:copy-of select="name()"将输出该元素的名称,没有标记(因此结果将不是格式良好的 xml)。

在过滤器测试为假的情况下,整个文档元素(包括其所有子元素)将被复制到输出中,并且不会进行进一步的处理。

$f/*/name()

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

 current()/name()

可以写成

 name(current())

在 XPath 1 中。

但是,既然您使用的是 saxon java 实现,为什么不简单地使用 saxon 9 而不是 saxon 6 并从 xslt 引擎十多年的进一步开发中受益呢?

于 2012-07-25T14:02:42.680 回答
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 无法识别此名称空间。这就是您收到错误的原因。

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

于 2012-07-25T14:26:21.287 回答