我正在阅读关于XSLT不能做什么的页面
http://www.dpawson.co.uk/xsl/sect2/nono.html#d1874e1080
并且有很多问题涉及动态命名或根据某些参数动态选择导入或模板。
答案总是:在XSLT中不可能。
现在,在XSLT中运行时无法解决某些问题的原因究竟是什么?我怎么知道在编译之前需要确定一些事情?
有些不可能的事情包括:
- 调用名称在运行时决定的模板
- 使用在运行时决定的模式应用模板
- 在运行时决定排序键
- 条件包含在运行时
在一个答案中说:
XSLT的基本处理模型(和许多其他语言一样!)是 它在开始阅读之前构建并编译样式表 输入数据。
这是编译时和运行时之间的区别。
它说xsl:include
是一个编译时问题
为什么在XSL中可以在运行时实现这样的功能?我想这与样式表在编译后无法更改这一事实有关,就像.exe不能,但我不是计算机科学家,所以......
我如何知道某些内容是否仅限于编译时或是否可以在运行时完成(重点放在XSLT上)?
答案 0 :(得分:3)
有些不可能的事情包括:
- 调用名称在运行时决定的模板
- 使用在运行时决定的模式应用模板
- 在运行时决定排序键
- 条件包含在运行时
这些可能字面不可能,但 根本不可能 - 即使在XSLT 1.0中也是如此。例如:
通过强大的技术实现与在运行时决定被调用模板的名称或应用模板的模式相同的效果,该技术用作 FXSL library的基础即可。 FXSL库在XSLT 1.0和XSLT 2.0中实现函数式编程。在XPath 3.0(和XSLT 3.0)中引入了function
数据类型。 Functions in 3.0 是XDM类型系统的第一类对象,可以定义,作为参数传递给其他函数或由函数返回。因此,人们可以使用函数,而不是调用或应用模板。
有很好的技术可以动态指定排序键,例如here
条件编译(包括xsl:import
或xsl:include
的编译)可以从使用xsl:use-when
属性的XSLT 2.0开始 - 请阅读以下有关此内容的更多信息
现在,究竟是什么原因导致某些事情无法实现 XSLT中的运行时?我怎么知道需要决定的事情 在编译之前?
我如何知道某些内容是否仅限于编译时或 是否可以在运行时完成(专注于XSLT)?
有一些简单的规则:
在编译时完全处理(编译)任何XSLT 指令。指令是任何XSLT元素,它是<xsl:stylesheet>
(或其同义词<xsl:transform>
)元素的子元素。
XML / XSLT instructions 的几乎所有属性都接受AVT( elements ) - 除select
属性之外的明显例外。
Attribute Value Templates 的name
属性不接受AVT或变量引用。
静态已知值
通常,静态已知值(已知且在编译期间不会更改)可用于控制XSLT处理器如何编译样式表。
XSLT 2.0中有一些函数可用于生成静态值,例如:
这些可用于指定为 function-available() 属性值的静态表达式。
use-when 属性可以在任何XSLT元素上指定 - 包括XSLT指令和XSLT指令,类似于其他编程语言中的预处理指令,例如{{1}它甚至可以在任何literal-result元素上指定,在这种情况下必须以绑定到XSLT命名空间的任何前缀为前缀(通常使用“xsl:”)。
在XSLT 3.0中引入了 use-when 和static variables。这为控制XSLT处理器的编译时行为提供了更多可能性。
XSLT 3.0的另一个密切相关的特性是所谓的static expressions。
要掌握这些强大的概念,需要阅读shadow attributes(目前只有XSLT 2.0和XSLT 1.0的书籍可用),或者观看good book和{{3} }。
答案 1 :(得分:2)
阅读规范,其中显示的是http://www.w3.org/TR/xslt20/#include
<!-- Category: declaration -->
<xsl:include
href = uri-reference />
因此href
属性的允许值是URI引用,而不是XPath表达式,也不是属性值模板。
xsl:call-template
相同,http://www.w3.org/TR/xslt20/#callable-components显示
<!-- Category: instruction -->
<xsl:call-template
name = qname>
<!-- Content: xsl:with-param* -->
</xsl:call-template>
因此name
属性值是限定名,不是XPath表达式,也不是属性值模板。
另一方面,如果您查看xsl:with-param
,http://www.w3.org/TR/xslt20/#element-with-param,则会找到
<xsl:with-param
name = qname
select? = expression
as? = sequence-type
tunnel? = "yes" | "no">
<!-- Content: sequence-constructor -->
</xsl:with-param>
select
属性允许XPath表达式。
因此,要确定某个属性是否允许您在运行时使用XPath表达式计算值,请查看XSLT 2.0规范中元素分别属性的定义。
答案 2 :(得分:1)
你实际上问了两个不同的问题:
现在,究竟是什么原因导致某些事情无法实现 XSLT中的运行时?
关于为什么语言是它的方式的问题可以被解释为询问关于何时以及为何做出特定决定的历史正确答案,或者它们可以被解释为对(事后)技术理由的请求。现状。如果被解释为对历史的请求,它们通常很难回答,因为除了非常罕见的情况(例如选择XPath if-then-else的语法)之外,决定不能归结为在一次会议上有意选择两种明确的备选方案。更常见的是,工作组内部对设计原则达成共识,这些原则可以为决策提供信息。其中一个设计原则是XSLT不是宏语言:表达式的结果是值,而不是扩展表达式。
xsl:call-template中的模板名称和xsl:apply-templates中的模式名称的动态评估请求多年来反复出现,虽然定义这样的功能并不困难,工作组从未觉得这是正确的方法。基本上这些是动态发货机制,工作组觉得这不是动态发货的正确方法。例如,在xsl:call-template中允许动态名称会限制优化器消除未使用的模板或“内联”模式的能力。它们在调用者的代码中。在XSLT中进行动态调度的主要方法一直是使用apply-templates和匹配模式,而XSLT 3.0引入了第二种方式,即使用高阶函数。
我怎么知道在编译之前需要确定某些事情?
答案:通过阅读规范,或者一本好的参考书。如果规范没有说动态计算某些东西,那么它就不是。