3

exsl:node-set 関数の仕組みがわかりません。

exsl:node-set に動的に入力するために展開して使用している XML があります。現在、この形式であるとしましょう:

<xsl:variable name="wrap">
    <nodes>
        <node/>
        <node/>
        <node/>
    </nodes>
</xsl:variable>
<xsl:variable name="wrapNodeSet" select="exsl:node-set($wrap)"/>

これは必要に応じて機能し、$wrapNodeSet を出力すると、上記のノード マークアップが表示されます。ルート ノード名は、name($wrapNodeSet/*) を使用して「ノード」として表示されます。

ここで、これを拡張して 2 つのノードを持ち、ノードセットを動的に設定する必要があります。そう:

    <xsl:variable name="wrap">
    <nodes tier="a">
        <node/>
        <node/>
        <node/>
    </nodes>
    <nodes tier="b">
        <node/>
        <node/>
        <node/>
    </nodes>
</xsl:variable>
<xsl:variable name="wrapNodeSet" select="exsl:node-set($wrap)/nodes[@tier='b']"/>

ノード セットの出力にはノード要素が含まれますが、ルート ノードの名前の出力は「ノード」に変更されます。

ノード要素がまだ出力されている理由を誰かが説明できますか?

4

3 に答える 3

0

If I've understood your question correctly, I believe 'intuitively' what's happening (the actual behind-the-scenes implementation details are probably a bit different) is in the first instance, your variable points to the 'anonymous node set' of the variable that wraps the <nodes> element. So doing name($wrapNodeSet/*) gets the names of all direct children of this anonymous node set, which in this case is just the name of the single <nodes> element.

In the second case, you've gone deeper than the anonymous node set and the variable contains the single nodes[@tier='b'] element directly. In this case name($wrapNodeSet/*) selects all direct children of that <nodes> element instead, and will return 3 instances of <node>. If you do a value-of select on this, it will default to displaying just the first one, which is why you'll just see "node" in the output.

To get the name of the root for the second instance, just do name($wrapNodeSet) directly and you should see "nodes". Doing $name(wrapNodeSet) in the first instance will not return anything, as the anonymous node set does not have a name.

于 2012-07-02T11:05:33.880 に答える
0

exslt:node-set には非常に非公式な仕様があり、おそらくどの実装が互いに異なるかについての詳細があります。これは、exstl:node-set への引数が結果ツリー フラグメント以外のものである場合など、エッジ ケースでは確かにそうです。

私が期待する動作は、exslt:node-set() が常に「ルート ノード」(XPath 2.0 で「ドキュメント ノード」と呼ばれるもの) を配信することです。XPath 1.0 で定義されているルート ノードには名前がありません。最初の例では、ルート ノードには「nodes」という名前の子要素が 1 つあります。2 番目の例では、ルート ノードに 2 つの要素の子があり、どちらも「ノード」という名前です。

「ルートノードの名前を出力すると「ノード」に変更される」と言いますが、これは紛らわしいです.XPath 1.0が定義する「ルートノード」には名前がないためです。実際に出力したものは何ですか?

于 2012-07-02T12:15:27.927 に答える
0
<xsl:variable name="wrapNodeSet" 
              select="exsl:node-set($wrap)/nodes[@tier='b']"/>

これは、拡張機能でnodes取得されたツリーから、その (要素) がvalue の属性を持つ任意の要素を選択します。node-set()nodestier'b'

それで:

name($wrapNodeSet/*)

に含まれる最初のノードの最初の子要素の名前を生成し$wrapNodeSetます。$wrapNodeSetには要素が1 つだけ含まれてnodesおり、nodes要素には子要素しかないため、そのnodeような最初の子要素はnode要素とその名前です。node要素の名前は です"node"

この結果に予期しないものが見られるのはなぜですか?

言い換えれば

ext:node-set()両方のケースでonを適用$wrapすると同じツリーが生成されますが、2 番目のケースでは、結果に異なる長い XPath 式を使用します。ext:node-set($wrap)したがって、これら 2 つの異なる XPath 式の評価から異なる結果が得られます。

于 2012-07-02T12:09:44.980 に答える