我知道下面的问题是初学者的一点点,但我需要你的帮助来了解一个基本的概念。
我想先说我是3年的XSLT程序员,但也有一些新的,很基本的东西,我一直在这里学习我从来不知道(在我的工作的人学习如何单独的程序,没有课程参与)。
我的问题是:什么是使用xsl:sequence
?
我一直在使用xsl:copy-of
,以复制节点是, xsl:apply-templates
,以modifiy节点,我选择和value-of
简单文字。
我从来没有使用必要xsl:sequence
。 我希望如果有人能告诉我的一个例子xsl:sequence
这是优选的或无I如上所述的那些无法实现的使用。
还有一两件事,我已经阅读有关xsl:sequence
当然定义,但我无法推断它是如何有用。
<xsl:sequence>
上的原子值(或原子值的序列)是相同的<xsl:copy-of>
都只是返回它们的输入的副本。 所不同的来当你考虑的节点。
如果$ n是一个单一的元素节点,例如由类似规定
<xsl:variable name="n" select="/html"/>
然后
<xsl:copy-of select="$n"/>
返回节点的副本 ,它具有相同的名称和子结构,但它是一个新的身份(没有父)的新节点。
<xsl:sequence select="$n"/>
返回节点$ N,返回的节点具有相同的父为$ n和是由等于它is
Xpath的运营商。
所不同的是在传统的(XSLT 1型)模板的使用几乎完全掩盖,你永远不会获得任何一种操作构造的结果被暗中复制到输出树所以实际上的结果xsl:sequence
不成副本被屏蔽。
<xsl:template match="a">
<x>
<xsl:sequence select="$n"/>
</x>
</xsl:template>
是相同的
<xsl:template match="a">
<x>
<xsl:copy-of select="$n"/>
</x>
</xsl:template>
无论作出新的元素节点和复制内容作为新节点的子节点的结果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>
产生
$ saxon9 -it main seq.xsl
<?xml version="1.0" encoding="UTF-8"?>
::
:: true
:: false
::
:: 1
:: 0
::
这里的结果xsl:sequence
和xsl:copy-of
是完全不同的。
最常见的用例的xsl:顺序返回从XSL结果:功能。
<xsl:function name="f:get-customers">
<xsl:sequence select="$input-doc//customer"/>
</xsl:function>
但它也可以在其他情况下派上用场,例如
<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>
这里的关键是,它返回到原来的节点的引用,它不会使新副本。
那么回到你使用某种类型的值xsl:sequence
为xsl:value-of
,尽管它的名字总是创建一个文本节点(因为XSLT 1.0)。 因此,在您使用的函数体
<xsl:sequence select="42"/>
返回一个xs:integer
值,你可以使用
<xsl:sequence select="'foo'"/>
到返回xs:string
值,
<xsl:sequence select="xs:date('2013-01-16')"/>
返回一个xs:date
值等。 当然还可以返回与例如序列<xsl:sequence select="1, 2, 3"/>
你不会希望在我看来,创建在这些情况下,文本节点,甚至一个元素节点,因为它是低效率的。
所以这是我取,用XSLT和XPath 2.0的退货或绕过这些类型和需要一个新的结构的值是需要一种新的基于架构类型的系统。
[编辑]迈克尔·凯说,在他的“XSLT 2.0和XPath 2.0程序员参考”关于xsl:sequence
:“在XSLT 2.0引入了这个无辜的看着指令对XSLT语言的能力具有深远的影响,因为这意味着XSLT指令和序列构造函数(因此功能和模板)成为能够返回由XPath数据模型允许的任何价值。没有它,XSLT指令只能用来创建一个结果树新节点,但是,他们也可以返回原子值并引用现有节点。“
另一个用途是创建只有当它有一个孩子的标签。 一个例子是必需的:
<a>
<b>node b</b>
<c>node c</c>
</a>
在某处,XSLT:
<xsl:variable name="foo">
<xsl:if select="b"><d>Got a "b" node</d></xsl:if>
<xsl:if select="c"><d>Got a "c" node</d></xsl:if>
</xsl:variable>
<xsl:if test="$foo/node()">
<wrapper><xsl:sequence select="$foo"/></wrapper>
</xsl:if>
:你可以在这里看到演示http://xsltransform.net/eiZQaFz
这是方式比测试这样每个标签更好:
<xsl:if test="a|b">...</xsl:if>
因为你最终会在两个地方进行编辑。 另外,处理速度将取决于哪些标签在你开关输入。 如果是从测试的最后一个,引擎会之前测试在场的每一个人。 为Foo $ /节点()是一个成语为“有子元素?”时,引擎可以优化它。 这样做,你缓解大家的生活。
文章来源: XSLT xsl:sequence. What is it good for..?