4

私は XSLT にかなり慣れていませんが、現在使用している CMS に使用する必要があります。私はすでに問題を思いつきましたが、基礎となる CMS についてあまり詳しく説明することなく、問題について説明しようと思います。私を助けるためにさらにコンテキストが必要な場合は、追加できます。

したがって、xml のノードが特定のノードの子孫であるかどうかをテストするだけです。

<xsl:if test="$currentNode::IsADescendantOf($someNode)">
Write this out.
</xsl:if>

アイデアはありますか?

前もって感謝します :)

4

5 に答える 5

5

ユニオン操作とノードセットのサイズ比較を使用する必要があります。

<xsl:if test="count($someNode|$currentNode/ancestor::*) = count($currentNode/ancestor::*)">
Write this out.
</xsl:if>

$someNodeが$ currentNodeの先祖である場合、 $someNode|$currentNode/ancestor::* は $currentNode/ancestor::* と同じノード セットを返します (ノード セットにはダブロンがありません)。

そうでない場合、結合のために、最初のノード セットは 2 番目のノード セットよりも 1 つ多くのノードを持つことになります。

于 2009-12-11T08:48:31.233 に答える
2

移植可能な (XPath 1.0 および 2.0) ソリューションは次のようになります。

<xsl:if test="
  $currentNode/ancestor::*[generate-id() = generate-id($someNode)]
">
Write this out.
</xsl:if>

これは祖先軸を上に移動し、その中のすべての要素をチェックします。いずれかの祖先の一意の ID が の一意の ID と一致する場合 (およびその場合のみ)、$someNode結果のノードセットは空ではありません。

空でないノード セットは true と評価されるため、条件が満たされます。

テスト -<baz>の子孫であるすべてを検索<foo>:

<xml>
  <foo>
    <bar>
      <baz>Test 1</baz>
    </bar>
  </foo>
  <baz>Test 2</baz>
</xml>

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="/">
    <xsl:variable name="someNode" select="//foo[1]" />

    <!-- test each <baz> node if it has <foo> as a parent -->
    <xsl:for-each select="//baz">
      <xsl:if test="
        ancestor::*[generate-id() = generate-id($someNode)]
      ">
        <xsl:copy-of select="." />
      </xsl:if>

    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

結果は

<baz>Test 1</baz>

for-each で行ったように、実際$currentNodeの現在のノードを参照している場合は、個別の変数は必要ないことに注意してください。デフォルトでは、すべての XPath は現在のノードに相対的です。

バリアントはトップダウンの方法です。ただし、効率は低くなります(おそらく数桁)。

<xsl:if test="
  $someNode[//*[generate-id() = generate-id($currentNode)]]
">
Write this out.
</xsl:if>
于 2009-12-11T10:21:35.900 に答える
1

答えは至って簡単、

あなたがしなければならないことは次のとおりです。

<xsl:if test="count(ancestor::somenode)>0">

    ...残りを追加します

ロジックは、ノードが somenode の子孫である場合、そのノードを 1 つ以上持つというものです。

于 2011-11-15T17:50:25.917 に答える
1

XSL/XPath リファレンスの「祖先」軸を見てください。

<xsl:if test="ancestor::*[. is $somenode]">

編集: 私はあなたと一緒に学んでいます。これが機能するかどうかを確認してください (このシステムで XSL デバッガーを使用できるようにしたいのですが :-)

于 2009-12-11T06:24:18.800 に答える
0

子孫チェック

最良の方法は、descendant::* 軸を使用することです。

このような XML があり<a>、最初のノードからの子孫ノードを一致させたい<alpha>場合。

XML

<root>
<!-- check for descendants of the following alpha node-->
<alpha>
  <!-- match the following node-->
  <a>...</a>
  <b>...</b>
  <c>...</c>
</alpha>
<alpha>
  <a>...</a>
  <c>...</c>
</alpha>
</root>

XSLT

<xsl:if test="/root/alpha[1]/descendant::a[. is current()]">

先祖チェック

これはおそらくほとんどの場合に機能します。

<xsl:if test="ancestor::*[name() = $node]">

どこ

<xsl:variable name="node" select="name(//alpha)"/>

または、比較するノードが複数あり、名前の一致ではなくノードの一致であることを確認する必要がある場合は、generate-id() を使用できます。

<xsl:variable name="node" select="generate-id(//alpha[3])"/>
<xsl:if test="ancestor::*[generate-id(.) = $node]">

isノードが必要であり、葉ノードには子孫がないため、祖先を比較するときに比較演算子を使用することはできません。

しかし、はるかに読みやすく柔軟であるため、descendant::* 軸を使用することをお勧めします。

于 2009-12-11T07:12:15.460 に答える