2012-02-06 8 views
6

ここには本当に単純なものがあります(少なくとも私は推測します)、私はちょっと手掛かりを得ません。xpath特定の先行する兄弟の末尾に戻る

サブノード値の1つで特定される特定のノードを取得するには、大きなXMLドキュメントを解析する必要があります。これまでのところ簡単。しかし、私はそのノードから比較的上向きに解析しようとすると、先祖の前の兄弟を述語を使って選択すると、ノードのリストが得られます。

Theorieでは、これは5列2行(下の例では)の表です。私は1つのフィールドのid要素だけを取得し、行の最初のフィールドに指定された名前を見つける必要があります。最初のフィールドは常に 'Link'タイプで、テキストを持つ名前サブノードがあります。これは取得するものです。

つまり、<id>XXX_X</i>を持つノードから、制御がxsi:type='Label'で名前のノードが次の先行する兄弟セルに移動する必要があります。ノード<id>MyItemId_1</>から、ノードから2番目の先行兄弟を取得する必要があります<id>MyItemId_4</id>私は5番目の先行兄弟を取得する必要があります。

これはサンプルXML作品です:

<cell> 
    <control xsi:type="Label"> 
     <id>1234</id> 
     <name>MyOtherItemName</name> 
     <message/> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Label"> 
     <id>MyOtherItemId_0</id> 
     <name/> 
     <message/> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Label"> 
     <id>MyOtherItemId_1</id> 
     <name/> 
     <message/> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Button"> 
     <id>MyOtherItemId_2</id> 
     <name>552</name> 
     <message/> 
     <type>Link</type> 
     <selected>false</selected> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Button"> 
     <id>MyOtherItemId_3</id> 
     <name>432</name> 
     <message/> 
     <type>Link</type> 
     <selected>false</selected> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Button"> 
     <id>MyOtherItemId_4</id> 
     <name>33</name> 
     <message/> 
     <type>Link</type> 
     <selected>false</selected> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Label"> 
     <id>1234</id> 
     <name>MyItemName</name> 
     <message/> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Label"> 
     <id>MyItemId_0</id> 
     <name/> 
     <message/> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Label"> 
     <id>MyItemId_1</id> 
     <name/> 
     <message/> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Button"> 
     <id>MyItemId_2</id> 
     <name>552</name> 
     <message/> 
     <type>Link</type> 
     <selected>false</selected> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Button"> 
     <id>MyItemId_3</id> 
     <name>432</name> 
     <message/> 
     <type>Link</type> 
     <selected>false</selected> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 
<cell> 
    <control xsi:type="Button"> 
     <id>MyItemId_4</id> 
     <name>33</name> 
     <message/> 
     <type>Link</type> 
     <selected>false</selected> 
    </control> 
    <selected>false</selected> 
    <style>Odd</style> 
</cell> 

私はこのXPathのを取得する必要がアイテム入手できますか:

//cell[control[type='Link']]/control[type='Link' and selected='false' and id='MyItemId_3']/id 

すなわち、セルのコントロールのIDを選択レンダリングされた表の第2行の第4列。私のテーブルの最初の列の2個の正しい細胞を与える

../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]]/control[name[node()]]/name 

:私はこのパスに従うことによって、行の最初のセルに移動しように、そのノードから

<name>MyOtherItemName</name> 
* * * * * * * * * * 
<name>MyItemName</name> 

私はそれだけで選択された2の最後の1を私に戻って与えるために得ることができないので、今では私の背中を壊します。

私はこの試み:

../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]][1]/control[name[node()]]/name 

Iの検索兄弟の正確にソートする述語を持つ先行兄弟選択であるが、I [1]セレクタとその述語を組み合わせることができないと思われるが。所望の最初の先行する兄弟「MyItemName」を選択する代わりに、先行するすべてのもの「MyOtherItemName」から最初の兄弟を選択する。

私は助けが必要です、ここに誰かが手がかりを持ち、正しい方向に私を指摘することができますように願っています。

私はこの仕事が http://www.bit-101.com/xpath/ にXMLをコピーして、ソフトウェアが何をすべきかをシミュレートするために、その上に連結xpathesと協力して取得するように設定まさに

//cell[control[type='Link']]/control[type='Link' and selected='false' and id='MyItemId_3']/id/../../preceding-sibling::cell[control[@xsi:type='Label' and name[node()]]]/control[name[node()]]/name 
+0

「MyItemName」を選択しようとしていますか?その行の最初のセルはどうですか?それは確かにそれのように見えません。 –

+0

私は5カラムテーブルとLinkタイプの最初のフィールドの間のどこかでそれを失いました。あなたはテーブルの類推なしにあなたの要件を言い換えることができると思いますか? –

+0

@ 42で同意します。あなたが試したことを示すことはしばしば良いことです。その作業に感謝しますが、この場合、私が試したのはあなたの元の要件を不明瞭にしています。最初にやろうとしていたことを正確かつ正確に伝えることを忘れてしまった。 –

答えて

11

私は何の問題を理解していません正確には存在するが、先行する兄弟はノード自体から文書の先頭に向かってソートされる。最も近い先行する兄弟を取得するには、preceding-sibling[1]を使用して最も遠い兄弟(ドキュメント順の最初の兄弟)を取得し、preceding-sibling[last()]を使用します。

+0

これは正しいですが、前の兄弟からの最初の兄弟の選択を、その述語に一致する兄弟からのみ使用するにはどうすればよいですか?先行兄弟を使用する[PREDICATE] [1]は機能しません - ノードを返しません –

+3

'preceding-sibling :: * [PREDICATE] [1]'を使用してください。 – choroba

+0

bit-101/xpathで試してみてください。セレクタとセレクタが混在していると動作しません。 –

1

、この作品あなたの更新をしません読んだ後:

//cell[control/id="MyItemId_4"]/preceding-sibling::cell[control[@xsi:type='Label'] and not(control/name='')][1] 

を私は名前のノードについて少しわからないよ:あなたが名前のノードまたは単に存在内のテキストが存在するかどうかをテストしたいです名前ノード自体の名前?

+0

http://www.bit-101.com/xpath/で試してもこれは動作しません。単に何も選択されません。前の兄弟がこの例で動作する前の最初の部分。 –

+0

名前ノードが存在し、テキストを持つことをテストする必要があります。 –

+0

ビット101で試しました。それは私のために働き、名前 "MyOtherItemName" –

1

YourWebElement.FindElement(By.XPath( "preceding-sibling :: * [1]"));

ここで、1は選択されたノードの上の兄弟を示しています。次に、先行するすべての兄弟を下から上に取得するために再帰を実行できます。

関連する問題