XSLT xsl:序列。到底有啥好处呢..?

Posted

技术标签:

【中文标题】XSLT xsl:序列。到底有啥好处呢..?【英文标题】:XSLT xsl:sequence. What is it good for..?XSLT xsl:序列。到底有什么好处呢..? 【发布时间】:2012-12-30 23:05:16 【问题描述】:

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

首先我想说的是,我是一名 3 年的 XSLT 程序员,但是我在这里学到了一些新的和非常基础的东西,我从来不知道(在我的工作中,任何人都学习如何单独编程,那里不涉及课程)。

我的问题是: xsl:sequence有什么用?

我一直使用xsl:copy-of 来复制节点,xsl:apply-templates 用于修改我选择的节点,value-of 用于简单文本。

我从来没有必要使用xsl:sequence。如果有人可以向我展示xsl:sequence 用法的示例,我将不胜感激,如果没有我上面提到的那些,这是首选或无法实现的。

还有一件事,我当然读过xsl:sequence 的定义,但我无法推断它有什么用处。

【问题讨论】:

【参考方案1】:

<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:sequencexsl:copy-of 的结果完全不同。

【讨论】:

【参考方案2】:

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="//customer"/>
    </xsl:when>
    <xsl:otherwise>
       <xsl:sequence select="//supplier"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

这里的关键是它返回对原始节点的引用,它不会创建新副本。

【讨论】:

在第二个示例中,这是否意味着 xsl:sequence 的性能更好?那么,copy-of 相对于 xsl:sequence 的优势在哪里? 我怀疑很少有你真正需要 xsl:copy-of 的情况。除非您使用validation=strict 或copy-namespaces=no,否则可能。在大多数情况下,使用 xsl:copy-of 代替 xsl:sequence 是无害的,但在某些情况下,它肯定会导致不必要且昂贵的复制,除非优化器足够聪明以防止它发生。但是在上面的例子中,这两者是不等价的:$x/.. 如果你进行复制,则不返回任何内容,但如果你使用 xsl:sequence 选择它们,则返回原始节点的父节点。 啊,我明白了。非常感谢!【参考方案3】:

要返回某个类型的值,您可以使用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 值等等。当然,您也可以使用例如返回序列&lt;xsl:sequence select="1, 2, 3"/&gt;.

在我看来,在这些情况下,您不希望创建文本节点甚至元素节点,因为它效率低下。

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

[edit]Michael Kay 在他关于xsl:sequence 的“XSLT 2.0 和 XPath 2.0 程序员参考”中说:“XSLT 2.0 中引入的这条看似无辜的指令对 XSLT 语言的能力产生了深远的影响,因为它意味着XSLT 指令和序列构造函数(以及函数和模板)能够返回 XPath 数据模型允许的任何值。没有它,XSLT 指令只能用于在结果树中创建新节点,但有了它,它们也可以返回原子值和对现有节点的引用。”。

【讨论】:

【参考方案4】:

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

<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/node() 是“有子元素吗?”的成语,引擎可以对其进行优化。这样做,您可以减轻每个人的生活。

【讨论】:

以上是关于XSLT xsl:序列。到底有啥好处呢..?的主要内容,如果未能解决你的问题,请参考以下文章

go语言到底有啥好处

SAP批次管理有啥好处呢?

SAP批次管理有啥好处呢

语义化的HTML结构到底有啥好处

春季自动装配有啥好处

Spring IoC有啥好处呢?