1

ノードの特定の子孫を除外する方法は? この方向では、式 *[not(self::nodetag)] は、返されたノード セット内の他のすべての子孫を受け入れて、ノードの子レベルで識別しているように見えます。式で div の下のすべてを選択する必要がありますが、そうでないノードは以下の例を参照してください。ツリー構造は同じままでなければなりません。

@Dimitri Novatchev によるアプローチの投稿は正しいようですが、HAP の実装には適していません。

このサンプル ドキュメントを使用すると、次のようになります。

<div>
  <span>
     <a>lala</a>
  </span>
</div>

HAP は、提案された式 /div/descendant::node()[not(self::a)] を使用して次の構造を返します。

<div>
  <span>
     <a>lala</a>
  </span>
</div>
<span>
     <a>lala</a>
 </span>

ネストされたスパン以外の別のタグがある場合、それは別のツリーとしても返されますが、この奇妙な動作について知っている人はいますか? HAPのバグですか?

ありがとう

4

2 に答える 2

1

式で div の下のすべてを選択する必要がありますが、そうではないノードが選択されますa。ツリー構造は同じままでなければなりません。

使用:

/div/descendant::node()[not(self::a)]

divこれは、(子孫) ではない最上位要素の子孫を選択しますa

XSLT ベースの検証:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:for-each select="/div/descendant::node()[not(self::a)]">
    <xsl:value-of select="concat('&#xA;', position(), '. &quot;')"/>
    <xsl:copy-of select="."/>"
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<div>
    <span>
        <a>lala</a>
    </span>
</div>

XPath 式が評価され、選択されたすべてのノードが適切なフォーマットで出力され、見やすくなります

1. "
    "

2. "<span>

   <a>lala</a>

</span>"

3. "
        "

4. "lala"

5. "
    "

6. "
"

ご覧のとおり、6 つのノード (1 つのspan要素、4 つの空白のみのテキスト ノード、1 つの非空白のみのテキスト ノード) が選択されていますが、いずれもa.

更新

コメントで、OP は、実際には XML ドキュメントを別のドキュメントに変換することを望んでいることを明らかにしました。このドキュメントでaは、a の子孫divは省略されています。

そのような変換の 1 つを次に示します

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="div//a"/>
</xsl:stylesheet>

この変換が同じ XML ドキュメント (上記) に適用されると、(私が推測するに) 必要な結果が生成されます。

<div>
   <span/>
</div>

div子孫を持つany の子孫のみを生成したい場合はa、ほぼ同じ変換が必要です。

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="div[.//a]"><xsl:apply-templates/></xsl:template>
 <xsl:template match="div//a"/>
</xsl:stylesheet>

これを上記と同じ XML ドキュメントに適用した結果は次のとおりです。

<span/>
于 2012-07-22T19:24:00.760 に答える
1

@Devela: XPath 式によって選択されたノードのセットを、リクエストを発行したアプリケーションによって表示される方法と混同しています。ノードをルートとするサブツリー全体を表示することによって、アプリケーションがノードを表示することは非常に一般的です。したがって、クエリが //div で、選択された div 要素の 1 つに<a>子孫としてノードが含まれている場合、その<a>要素を含む結果が表示されます。<a>XPath 式は要素を選択していないため、XPath 式を変更してもこれを変更することはできません。結果の表示方法を変更することによってのみ変更できます。

ここで、 が省略されていることを除いてソース内の要素<div>と同様の要素を表示したい場合、XPath が実行できる範囲外になります。XPath は、入力ツリー内のノードのサブセットのみを選択できます。変更されたツリーを作成することはできません。そのためには、XSLT または XQuery が必要です。<div><a>

于 2012-07-22T21:45:54.637 に答える