42

XSLTの例をいくつか読んで、そのコードを見つけました。

<xsl:apply-template select="@*|node()"/>

どういう意味ですか?

4

3 に答える 3

52

XPath式は、属性ノード()と他のすべてのタイプのXMLノード( )の和集合@* | node()を選択します。@*node()

の省略形ですattribute::* | child::node()

XSLTでは、XPathはコンテキストノードを基準にしており、デフォルトの選択child軸であるため、式

  • コンテキストノードのすべての属性と直接の子を選択select="..."します(たとえば、で式として使用される場合<xsl:apply-templates>
  • コンテキストに関係なく、すべての属性ノードと他のノードに一致match=""します(で式として使用される場合<xsl:template>)。ノードの選択と一致には違いがあることに注意してください。コンテキストノードは選択にのみ関係します。

次のノードがコンテキストノードであると想像してください。

<xml attr="value">[
  ]<child />[
  ]<!-- comment -->[
  ]<child>
    <descendant />
  </child>[
]</xml>

node()は、両方の<child>ノードだけでなく、4つの空白のみのテキストノード(表示のためにで示されます)とコメント[も選択します。]が選択され<descendant>ていません。

XMLの特別な特徴は、属性ノードがそれらが属する要素の子ではないことです(ただし、属性の親はそれが属する要素です)。

この非対称の関係により、それらを個別に選択する必要があります。したがって、@*

コンテキストノードに属するすべての属性ノードと一致するため、attr="value"も選択されます。

|XPathユニオン演算子です。2つの別々のノードセットから単一のノードセットを作成します。

<xsl:apply-templates>次に、選択したすべてのノードに適切なものを見つけて<xsl:template>、そのノードに対して実行します。これは、前述のテンプレートマッチング部分です。

于 2012-06-23T06:56:09.873 に答える
22

Tomalakの優れた答えに追加するには:

その場合、ほとんどの場合、次<xsl:apply-template select="@*|node()"/>のようなテンプレートで使用されます。

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

これは、IDルールまたは「IDテンプレート」と呼ばれます。

最も基本的で強力なXSLTデザインパターンの1つは、IDルールの使用とオーバーライドです

変換がIDルールのみで構成されている場合、変換の結果はソースXMLドキュメント自体になります。これが、テンプレートが「IDルール」と呼ばれる理由です。

なぜこの結果が得られるのですか?

簡単な答えは:XSLT処理モデルのためです。

より詳細な説明は上から始める必要があります:

node()

任意の要素、テキストノード、コメント、または処理命令に一致します。document-(root)-nodeも。と一致しnode()ます。

任意のドキュメントツリーの「リーフ」ノードを想像できます。これらは、テキストノード、コメント、処理命令など、それ自体に子を持たないノードです。空の要素もリーフノードと見なす必要があります。

IDルールは、最初に、ドキュメントノードのすべての子ノードに対して実行(適用)するために選択されます(これらは、単一の最上位要素と、コメントまたは処理命令の兄弟です)。一致したノードは浅くコピーされ、それが非要素リーフノードである場合、<xsl:apply-templates select="node()|@*"/>命令はノードまたは属性を選択しません。

一致したノードが要素である場合、それは浅くコピーされ、<xsl:apply-templates select="node()|@*"/>命令によって同じテンプレートが(変換コードに他のテンプレートがないため)、その各属性とその子ノードのそれぞれに適用されます。

これは、リーフノードまたは属性に到達するまでXMLドキュメントのすべてのノードの処理を駆動し<xsl:apply-templates select="node()|@*"/>、その場所で子または属性ノードを選択しない再帰です。

于 2012-06-23T14:31:18.473 に答える
9

@Tomalakの最初の正解おめでとうございます。ダニは彼の答えに行くべきです。彼の答えにいくつかの説明を追加します。

注1

... @ * | node()は...の和集合を選択します

| 演算子は、2つのオペランドの和集合を返すだけでなく、ドキュメント順に並べ替えて重複を削除します。削除する重複がないため、重複排除の部分はここでは関係ありませんが、並べ替えの部分は注目に値します。より正しいバージョンは次のようになります...

... @ * | node()は、ドキュメント順にソートされた...の和集合を選択します。

注2

...および他のすべてのタイプのXML子ノード(node())

これは広く真実ですが、誤解を招く恐れがあります。ほとんどの人が「XML子ノード」を読むとき、彼らはDOMの意味で子ノードを考えます。しかし、これは選択されているものではありません。XDMノードのみが選択されます。説明については、次のドキュメントを参照してください。

<?xml version="1.0" encoding="ISO-8859-1"?>
<root-element my-attrib="myattrib-vaue" xmlns:hi="www.abc.com"><child-element />
abc&apos;def
</root-element>

ここで、コンテキストアイテムが「ルート要素」であると仮定します。Tomalakの答えの読者は、「@ * | node()」によって何が選択されるかという質問をされます。DOMモデルを考えている人にとって、Tomalakの答えが意味することは、次の6つが選択されているということです。

  • my-attrib属性
  • ノードスペース属性(DOMの真の属性)
  • 子要素ノード
  • 'abc'ビット
  • エンティティ参照
  • 'def'ビット。

しかし、これはXSLTでは実際には当てはまりません。実際に選択されるのは...

  • my-attrib属性
  • 子要素ノード
  • XDMテキストノード。「abc'def」のような3つのDOMテキストノードを連結したものです。

したがって、より正確なステートメントは...

XPath式@*| node()は、(XDMの意味でのコンテキストアイテムの属性ノードとコンテキストアイテムのXML子ノード)の和集合をドキュメント順に選択します。XDモデルは、DOM内にあるエンティティ定義などの一部のノードタイプを無視し、連続するテキストDOMノードは1つのXDMテキストノードに連結されます。

于 2012-06-24T04:58:55.480 に答える