通过参数将XML传递给XSL模板是否可以?例如,下面我有模板body
调用模板test1
,它通过参数var1
传递一些XML。然后我尝试使用XPATH
a
<xsl:template name="test1">
<xsl:param name="var1" />
<fo:block>
<xsl:value-of select="$var1/a" />
</fo:block>
</xsl:template>
<xsl:template name="body">
<xsl:call-template name="test1">
<xsl:with-param name="var1" >
<a>foo</a>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
问题是,这导致我的XSL解释器失败并出现无用的错误消息。我被迫使用一个封闭的源供应商系统来生成文档,所以我无法调试。但在我进一步研究之前,我正在寻找确认这是XSL的有效用法。
答案 0 :(得分:14)
<xsl:template name="body"> <xsl:call-template name="test1"> <xsl:with-param name="var1" > <a>foo</a> </xsl:with-param> </xsl:call-template> </xsl:template>
由于臭名昭着的RTF(结果树片段)类型,传递给模板的$var1
参数在XSLT 1.0 / XPath 1.0中几乎无法使用。
来自W3C XSLT 1.0 spec 。:
11.1结果树片段
变量引入了额外的数据类型 表达语言。这个 其他数据类型称为结果 树片段。变量可以绑定 到结果树片段而不是 四种基本XPath数据类型之一 (字符串,数字,布尔值,节点集)。一个 结果树片段代表一个 结果树的片段。结果 树片段被等同地处理 到一个只包含一个的节点集 单根节点。然而 结果树上允许的操作 片段是那些的子集 允许在节点集上。 <强>一种 结果允许操作 树片段仅在该操作时 将被允许在一个字符串( 对字符串的操作可能涉及 首先将字符串转换为 数字或布尔值)。特别是它 不允许使用
/
,//
, 和结果树上的[]
运算符 片段。当允许的操作 在结果树上执行 片段,它完全按照 它会相当于 节点集。强>复制结果树片段时 进入结果树(见[11.3使用 变量和参数的值 使用xsl:copy-of]),然后是所有节点 这是根节点的子节点 添加等效节点集 序列到结果树。
表达式只能返回值 输入结果树片段 引用类型结果的变量 树片段或调用扩展 返回结果树的函数 片段或获取系统属性 其值为结果树片段。
为了避免这种严重的设计决策,几乎每个XSLT处理器都有自己的扩展功能,通常名为xxx:node-set()
,其中xxx
前缀必须绑定到供应商定义的命名空间。
<强>解决方案强>:
确切了解XSLT处理器供应商提供的此扩展功能的名称。
或者,如果您的XSLT处理器支持EXSLT,请使用EXSLT定义的 exsl:node-set()
扩展功能。
以下是一些特定于供应商的命名空间:
MSXML和.NET XslCompiledTransform,XslCompiledTransform :
xmlns:vendor="urn:schemas-microsoft-com:xslt"
Xalan (注意,函数名称是:xxx:nodeset()
!):
xmlns:vendor="http://xml.apache.org/xalan"
撒克逊(6.x):
xmlns:vendor="http://icl.com/saxon"
<强>的Altova:强>
xmlns:vendor="http://www.altova.com/xslt-extensions"
所有实施EXSLT的XSLT处理器:
xmlns:vendor="http://exslt.org/common"
如果<xsl:param>
的主体不是动态构造的,可以避免
xxx:node-set()
以下列方式运作:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:variable name="vrtfparamXML">
<a>
<b>foo</b>
</a>
</xsl:variable>
<xsl:variable name="vparamXML" select=
"document('')/*/xsl:variable
[@name='vrtfparamXML']/*"/>
<xsl:template match="/">
<xsl:copy-of select="$vparamXML/b"/>
</xsl:template>
</xsl:stylesheet>
当此转换应用于任何XML文档(未使用)时,结果是RTF的通缉子:
<b xmlns:xsl="http://www.w3.org/1999/XSL/Transform">foo</b>
注意:XSLT 2.0 / XPath 2.0摆脱了RTF“类型”,并且有一个访问临时树并使用XPath 2.0的全部功能导航它们没有任何问题