首页 > 解决方案 > 在 XSLT-3.0 中使用“xsl:original”链接命名模板时发生“保留命名空间”错误

问题描述

我正在尝试使用“xsl:original”功能在 XSLT 3.0 中链接命名模板,但我得到一个保留名称命名空间错误。

例如,我使用了一个add-atts在两个包含的样式表中定义的命名模板:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" version="3.0">

  <xsl:template match="/">
    <root>
      <xsl:apply-templates select="root/line"/>
    </root>
  </xsl:template>

  <xsl:template match="line">
    <xsl:copy>
      <xsl:call-template name="add-atts"/>  <!-- USED HERE -->
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:import href="add-foo.xsl"/>  <!-- DEFINED HERE -->
  <xsl:import href="add-bar.xsl"/>  <!-- DEFINED HERE -->

</xsl:stylesheet>

第一个包含的样式表有一个命名模板,它添加了一个@foo属性:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" version="3.0">

  <xsl:template name="add-atts">
    <xsl:attribute name="att1">foo</xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

第二个包含的样式表有一个同名的命名模板(由于排序而优先),它添加了一个@bar属性,然后尝试从前一个文件中调用覆盖的模板:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" version="3.0">

  <xsl:template name="add-atts">
    <xsl:attribute name="att2">bar</xsl:attribute>
     <xsl:call-template name="xsl:original"/>  <!-- HERE -->
  </xsl:template>

</xsl:stylesheet>

当我在以下输入文件上运行它时

<root>
  <line>1</line>
  <line>2</line>
  <line>3</line>
</root>

我收到以下错误:

$ java -jar .../Saxon-HE-9.9.1-4.jar in.xml trans.xsl
Static error in xsl:call-template/@name on line 8 column 46 of add-bar.xsl:
  XTSE0080: Namespace prefix xsl refers to a reserved namespace
Errors were reported during stylesheet compilation

命名空间已声明,xsl:XSLT 版本设置为 3.0,用法与此示例中已弃用的 XSL-LIST 邮件列表中显示的相同。我错过了什么?

(实际意图是在为 DITA Open Toolkit 创建插件时链接命名模板。)

提前致谢!

标签: xslt-3.0

解决方案


该功能存在于包的新 XSLT 3 特性的上下文中,请参阅https://www.w3.org/TR/xslt-30/#re​​fer -to-overridden 。您链接到的规范和线程似乎都没有在简单xsl:import的上下文中引入此功能。

为了给您一个示例,说明如何在 XSLT 3 中将其与包一起使用,假设您有第一个包

<?xml version="1.0" encoding="UTF-8"?>
<xsl:package 
    name="http://example.com/packages/ex1"
    package-version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:template name="add-atts" visibility="public">
        <xsl:attribute name="att1">foo</xsl:attribute>
    </xsl:template>    

</xsl:package>

然后您可以编写第二个包,覆盖该命名模板并使用<xsl:call-template name="xsl:original"/>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:package 
    name="http://example.com/packages/ex2"
    package-version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:use-package name="http://example.com/packages/ex1">
        <xsl:override>
            <xsl:template name="add-atts" visibility="public">
                <xsl:attribute name="att2">bar</xsl:attribute>
                <xsl:call-template name="xsl:original"/>
            </xsl:template>           
        </xsl:override>
    </xsl:use-package>

</xsl:package>

最后你可以使用第二个包:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" version="3.0">

    <xsl:use-package name="http://example.com/packages/ex2"></xsl:use-package>

    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="root/line"/>
        </root>
    </xsl:template>

    <xsl:template match="line">
        <xsl:copy>
            <xsl:call-template name="add-atts"/>  <!-- USED HERE -->
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

从命令行使用 Saxon ,当您运行主样式表时,您需要确保在 Windows 和Linux 上使用-lib选项提供两个包的文件名列表。-lib:package1.xsl;package2.xsl-lib:package1.xsl:package2.xsl


推荐阅读