web-dev-qa-db-ja.com

XSLT xsl:sequence。それは何のために良いのですか?

次の質問は少し初心者ですが、基本的な概念を理解するにはあなたの助けが必要です。

私は最初に3年間XSLTプログラマーであると言いたいのですが、ここで学んだ新しい基本的な事柄がいくつかあります。関与)。

私の質問は:xsl:sequenceの使用法は何ですか?

xsl:copy-ofを使用してノードをそのままコピーし、xsl:apply-templatesを使用して選択したノードを変更し、value-ofを使用して単純なテキストを作成しました。

xsl:sequenceを使用する必要はありませんでした。誰かが私が上で述べたものなしで好まれるまたは達成できないxsl:sequenceの使用例を見せてくれれば幸いです。

もう1つ、もちろんxsl:sequenceの定義について読んだことがありますが、その有用性を推測することはできませんでした。

33
user1942476

アトミック値(またはアトミック値のシーケンス)の<xsl:sequence>は、<xsl:copy-of>と同じです。どちらも入力のコピーを返すだけです。違いは、ノードを検討するときに生じます。

$ nが単一要素ノードの場合、たとえば次のように定義されている場合

<xsl:variable name="n" select="/html"/>

それから

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

ノードのcopyを返します。名前と子構造は同じですが、新しいID(および親なし)を持つnewノードです。

<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>

両方とも新しい要素ノードを作成し、copy新しいノード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の結果は根本的に異なります。

40
David Carlisle

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>

ここで重要なことは、元のノードへの参照を返し、新しいコピーを作成しないことです。

23
Michael Kay

特定のタイプの値を返すには、名前が常にテキストノードを作成するにもかかわらず、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の新しいスキーマベースの型システムでは、これらの型の値を返すまたは渡す方法が必要であり、新しいコンストラクトが必要でした。

[編集] Michael Kayはxsl:sequenceについて「XSLT 2.0およびXPath 2.0プログラマー向けリファレンス」で次のように述べています。「XSLT 2.0命令とシーケンスコンストラクター(および関数とテンプレート)は、XPathデータモデルで許可されている値を返すことができるようになります。アトミック値と既存ノードへの参照。」。

6
Martin Honnen

別の用途は、子がある場合にのみタグを作成することです。例が必要です:

<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>

最終的には2つの場所で編集することになります。また、処理速度は入力に含まれるタグによって異なります。テストの最後の場合、エンジンは以前の全員の存在をテストします。 $ foo/node()は「子要素はありますか?」のイディオムなので、エンジンはそれを最適化できます。そうすることで、皆さんの生活が楽になります。

0
programaths