次の質問は少し初心者ですが、基本的な概念を理解するにはあなたの助けが必要です。
私は最初に3年間XSLTプログラマーであると言いたいのですが、ここで学んだ新しい基本的な事柄がいくつかあります。関与)。
私の質問は:xsl:sequence
の使用法は何ですか?
xsl:copy-of
を使用してノードをそのままコピーし、xsl:apply-templates
を使用して選択したノードを変更し、value-of
を使用して単純なテキストを作成しました。
xsl:sequence
を使用する必要はありませんでした。誰かが私が上で述べたものなしで好まれるまたは達成できないxsl:sequence
の使用例を見せてくれれば幸いです。
もう1つ、もちろんxsl:sequence
の定義について読んだことがありますが、その有用性を推測することはできませんでした。
アトミック値(またはアトミック値のシーケンス)の<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:sequence
とxsl:copy-of
の結果は根本的に異なります。
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
として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データモデルで許可されている値を返すことができるようになります。アトミック値と既存ノードへの参照。」。
別の用途は、子がある場合にのみタグを作成することです。例が必要です:
<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()は「子要素はありますか?」のイディオムなので、エンジンはそれを最適化できます。そうすることで、皆さんの生活が楽になります。