40

我知道下面的问题有点初学者,但我需要你的帮助来理解一个基本概念。

首先我想说的是,我是一名XSLT程序员已经三年了,但我在这里学到了一些新的、非常基础的东西,我从来都不知道(在我的工作中,任何人都会独自学习如何编程,不需要任何课程)。

我的问题是:的用法是什么xsl:序列?

我一直在使用xsl:复制为了按原样复制节点,xsl:apply-templates应用模板为了修改我选择的节点和价值用于简单文本。

我从来没有必要使用xsl:序列。如果有人能给我举个例子,我将不胜感激xsl:序列如果没有我上面提到的用法,则是首选用法或无法实现的用法。

还有一件事,我读过关于xsl:序列当然,我无法推断它是如何有用的。

0

4个答案4

重置为默认值
50

<xsl:sequence>原子值(或原子值序列)与<xsl:copy-of>两者都只返回输入的副本。当考虑节点时,就会出现差异。

如果$n是单个元素节点,例如由以下内容定义

<xsl:variable name=“n”select=“/html”/>

然后

<xsl:copy-of-select=“$n”/>

返回一个复制节点的名称和子结构相同,但它是一个新的具有新标识(无父级)的节点。

<xsl:sequence select=“$n”/>

返回节点$n,返回的节点与$n具有相同的父级,并且通过Xpath操作员。

这种差异在传统(XSLT 1样式)模板使用中几乎完全掩盖了,因为您永远无法访问构造函数的结果隐式地复制到输出树中,因此xsl:sequence(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=”数据:,f“><xsl:variable name=“s”><x> 您好</x></xsl:variable><xsl:template name=“main”>::::<xsl:value-of-select=“$s/x是f:s($s/x)”/>::<xsl:value-of-select=“$s/x是f:c($s/x)”/>::::<xsl:value-of-select=“计数(f:s($s/x)/..)”/>::<xsl:value-of-select=“计数(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序列.xsl<?xml版本=“1.0”编码=“UTF-8”?>::::true::false:::: 1:: 0::

这里是的结果xsl:sequence(xsl:sequence)xsl:复制完全不同。

32

xsl:sequence最常见的用例是从xsl:function返回结果。

<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=“//客户”/></xsl:when><xsl:否则><xsl:sequence select=“//供应商”/></xsl:否则></xsl:choose></xsl:variable>

这里的关键是,它返回对原始节点的引用,而不生成新的副本。

2
  • 1
    在第二个示例中,这是否意味着xsl:sequence的性能更好?那么,相对于xsl:sequence,复制的优势在哪里呢? 2015年11月11日13:05
  • 5
    我怀疑很少有情况下您真的需要xsl:copy-of。除非您使用validation=strict或copy-namespaces=no。在大多数情况下,使用xsl:copy-of而不是xsl:sequence是无害的,但在某些情况下,除非优化器足够聪明,可以防止这种情况发生,否则可能会导致不必要且昂贵的复制。但在上面的示例中,这两者并不等价:$x/。。如果进行复制,则不返回任何内容,但如果使用xsl:sequence选择原始节点,则返回它们的父节点。 2015年11月11日13:16
9

返回您使用的特定类型的值xsl:序列作为xsl:值尽管它的名字总是创建一个文本节点(自XSLT 1.0以来)。所以在函数体中使用

<xsl:sequence select=“42”/>

返回xs:整数值,您将使用

<xsl:sequence select=“'foo'”/>

返回xs:string价值和

<xsl:sequence select=“xs:date('2013-01-16')”/>

返回xs:日期值等。当然,您也可以使用例如。<xsl:sequence select=“1,2,3”/>

在我的视图中,在这些情况下,您不想创建文本节点甚至元素节点,因为这样效率很低。

这就是我的观点,对于新的基于模式的XSLT和XPath 2.0类型系统,需要一种方法来返回或传递这些类型的值,需要一个新的构造。

[编辑]迈克尔·凯在他的“XSLT 2.0和XPath 2.0程序员参考”中谈到xsl:序列:“XSLT2.0中引入的这个看起来很无辜的指令对XSLT语言的功能有着深远的影响,因为它意味着XSLT指令和序列构造函数(以及函数和模板)能够返回XPath数据模型允许的任何值。没有它,XSLT指令只能用于在结果树中创建新节点,但有了它,它们还可以返回原子值和对现有节点的引用。".

0
0

另一个用途是仅当标记有子标记时才创建标记。需要一个示例:

<a><b>节点b</b><c> 节点c</c></a>

XSLT中的某个位置:

<xsl:variable name=“foo”>获得一个“b”节点获得“c”节点</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/node()是“有子元素吗?”的习惯用法,所以引擎可以优化它。这样做可以让每个人的生活都变得轻松。

你的答案

点击“发布您的答案”,即表示您同意我们的服务条款并确认您已阅读我们的隐私政策

不是你想要的答案吗?浏览标记的其他问题问你自己的问题