2009-07-11 22 views
4

私は、このような何か文書を持っている:どのように私は連続して与えられた要素の後に、すべてのBの要素を選択することができ、XPathを使用しXpathでこれらの要素を選択する方法は?

<root> 
    <A node="1"/> 
    <B node="2"/> 
    <A node="3"/> 
    <A node="4"/> 
    <B node="5"/> 
    <B node="6"/> 
    <A node="7"/> 
    <A node="8"/> 
    <B node="9"/> 
</root> 

を?

これは次のようなものです:silk :: B、の直後にという要素があることを除きます。

私がA(ノード== 1)にいる場合は、ノード2を選択します。 私がA(ノード== 3)であれば、何も選択しません。 私がAノード(ノード== 4)にいる場合、5と6を選択します。

xpathでこれを実行できますか? EDIT:XSLスタイルシートのselect文の中にあります。


EDIT2:私は、一意の識別子として、様々な要素にノード属性を使用する必要はありません。私は自分のポイントを説明する目的のためだけにノード属性を含めました。実際のXML文書では、私は一意の識別子として使用する属性を持っていません。 xpath "following-sibling :: UL [先行兄弟:: LI [1]/@ノード=現在()/ @ノード]" ノード属性のキーは、私が望むものではありません。

答えて

5

短い答え(これがタグ付けされているので、)(現在はokですと仮定すると、XSLT):

following-sibling::B[preceding-sibling::A[1]/@node = current()/@node] 

例スタイルシート:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml"/> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="/root/A"/> 
    </xsl:template> 

    <xsl:template match="A"> 
     <div>A: <xsl:value-of select="@node"/></div> 
     <xsl:apply-templates select="following-sibling::B[preceding-sibling::A[1]/@node = current()/@node]"/> 
    </xsl:template> 

    <xsl:template match="B"> 
     <div>B: <xsl:value-of select="@node"/></div> 
    </xsl:template> 
</xsl:stylesheet> 

幸運!

+0

ああ、ありがとう、これは完璧です! – Cheeso

+0

これは、 'current()'が相対的なロジックのステートメントの位置付けに役立つことを思い出させるのに役立ちます。 –

1

解決策は、最初にfollowing-sibling::*を使用して次のすべてのノードを集め、最初のノードを取得して「B」ノードにする必要があります。

following-sibling::*[position()=1][name()='B'] 
+0

これは良いアイデアです。これは私が理解できる。ありがとうございました。 – Cheeso

3

@クリスニールセンの答えは正しいアプローチであるが、それは比較の属性が一意でない場合は不確実性を残します。これを解決するのがより正しい方法は次のとおりです。

following-sibling::B[ 
    generate-id(preceding-sibling::A[1]) = generate-id(current()) 
] 

これはpreceding-sibling::Aだけではなく、いくつかの属性値を比較すること、現在Aから同一であることを確認します。ユニークであることが保証されている属性がない限り、これは唯一の安全な方法です。

+0

+1;私は次の兄弟:: B(count(先行兄弟:: A [1] |現在())= 1]と言うつもりでしたが、あなたのやり方は分かりやすいようです。 –

+0

IMHOでは、ノードIDを決定する 'count(...)'メソッドは 'generate-id()'メソッドより意味的に劣っていますが、時にはそれを使用することもあります。文脈に少し依存しますが、一般的に私はもっと明示的に 'generate-id()'を選びます。 – Tomalak

関連する問題