use*_*476 35 xslt xslt-2.0 xslt-1.0
我知道以下问题是一些初学者,但我需要你的帮助才能理解一个基本概念.
我想首先说我是一名XSLT程序员已经3年了但是我在这里学到了一些新的和相当基础的东西我从来不知道(在我的工作中,任何人都学会了如何单独编程,没有课程参与).
我的问题是:用法是xsl:sequence什么?
我一直在使用xsl:copy-of,以便按原样复制节点,xsl:apply-templates以便修改我选择的节点和value-of简单的文本.
我从来没有必要使用xsl:sequence.如果有人可以向我展示一个xsl:sequence使用的例子,我会很感激,如果没有我上面提到的那些,这是优选的或不可能实现的.
还有一件事,我读过有关xsl:sequence课程的定义,但我无法推断它是如何有用的.
Dav*_*sle 41
<xsl:sequence>在一个原子值(或原子值序列)上<xsl:copy-of>只是返回它们的输入副本.考虑节点时会出现差异.
如果$ n是单个元素节点,例如由类似的东西定义
<xsl:variable name="n" select="/html"/>
Run Code Online (Sandbox Code Playgroud)
然后
<xsl:copy-of select="$n"/>
Run Code Online (Sandbox Code Playgroud)
返回节点的副本,它具有相同的名称和子结构,但它是具有新标识的新节点(并且没有父节点).
<xsl:sequence select="$n"/>
Run Code Online (Sandbox Code Playgroud)
返回节点$ n,返回的节点与$ n具有相同的父节点,并且由isXpath运算符等于它.
在传统的(XSLT 1样式)模板用法中几乎完全掩盖了差异,因为您永远无法访问任一操作的结果,构造函数的结果被隐式复制到输出树,因此xsl:sequence不会复制的事实被屏蔽.
<xsl:template match="a">
<x>
<xsl:sequence select="$n"/>
</x>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
是相同的
<xsl:template match="a">
<x>
<xsl:copy-of select="$n"/>
</x>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
两者都创建一个新的元素节点,并将内容的结果复制为新节点的子节点x.
但是,如果使用函数,很快就会出现差异.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="data:,f">
<xsl:variable name="s">
<x>hello</x>
</xsl:variable>
<xsl:template name="main">
::
:: <xsl:value-of select="$s/x is f:s($s/x)"/>
:: <xsl:value-of select="$s/x is f:c($s/x)"/>
::
:: <xsl:value-of select="count(f:s($s/x)/..)"/>
:: <xsl:value-of select="count(f:c($s/x)/..)"/>
::
</xsl:template>
<xsl:function name="f:s">
<xsl:param name="x"/>
<xsl:sequence select="$x"/>
</xsl:function>
<xsl:function name="f:c">
<xsl:param name="x"/>
<xsl:copy-of select="$x"/>
</xsl:function>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
产生
$ saxon9 -it main seq.xsl
<?xml version="1.0" encoding="UTF-8"?>
::
:: true
:: false
::
:: 1
:: 0
::
Run Code Online (Sandbox Code Playgroud)
这里的结果xsl:sequence和xsl:copy-of根本不同.
Mic*_*Kay 26
xsl:sequence最常见的用例是从xsl:function返回结果.
<xsl:function name="f:get-customers">
<xsl:sequence select="$input-doc//customer"/>
</xsl:function>
Run Code Online (Sandbox Code Playgroud)
但是,例如,它在其他情况下也可以派上用场
<xsl:variable name="x" as="element()*">
<xsl:choose>
<xsl:when test="$something">
<xsl:sequence select="//customer"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="//supplier"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Run Code Online (Sandbox Code Playgroud)
这里的关键是它返回对原始节点的引用,它不会创建新的副本.
那么回到你使用某种类型的值xsl:sequence作为xsl:value-of尽管它的名字总是创建一个文本节点(因为XSLT 1.0).所以在你使用的函数体中
<xsl:sequence select="42"/>
Run Code Online (Sandbox Code Playgroud)
要返回一个xs:integer值,你会使用
<xsl:sequence select="'foo'"/>
Run Code Online (Sandbox Code Playgroud)
返回一个xs:string值和
<xsl:sequence select="xs:date('2013-01-16')"/>
Run Code Online (Sandbox Code Playgroud)
返回xs:date值等等.当然你也可以用例如返回序列<xsl:sequence select="1, 2, 3"/>.
在我的视图中,您不希望在这些情况下创建文本节点甚至元素节点,因为它效率低下.
所以这是我的看法,使用基于XSLT和XPath 2.0的新的基于模式的类型系统,需要一种方法来返回或传递这些类型的值,并且需要新的构造.
[编辑] Michael Kay在他的"XSLT 2.0和XPath 2.0程序员的参考资料"中说xsl:sequence:"XSLT 2.0中引入的这种无辜的指令对XSLT语言的功能有着深远的影响,因为它意味着XSLT指令和序列构造函数(因此,函数和模板能够返回XPath数据模型允许的任何值.没有它,XSLT指令只能用于在结果树中创建新节点,但是使用它,它们也可以返回原子值和引用现有节点."