XPath kullanarak belirli bir özniteliğe sahip ilk öğeyi seçme


301

XPath bookstore/book[1], altındaki ilk kitap düğümünü seçer bookstore.

Daha karmaşık bir koşulla eşleşen ilk düğümü nasıl seçebilirim, örneğin eşleşen ilk düğümü /bookstore/book[@location='US']

Yanıtlar:


445

kullanın:

(/bookstore/book[@location='US'])[1]

Bu, ilk olarak yer özelliği 'ABD'ye eşit olan kitap öğelerini alır. Daha sonra bu setten ilk düğümü seçecektir. Bazı uygulamalar için gerekli olan parantez kullanımına dikkat edin.

/bookstore/book[1][@location='US']İlk öğenin bu konum özelliğine sahip olmadığı sürece bunun aynı olmadığını unutmayın .


Aynı şeyi // bookstore / book [@ location = 'US'] için nasıl yapabilirim?
Alexander V.Ilyin

7
Bu, tüm kitapları 'ABD'den alacak. (/ kitabevi / kitap [@ location = 'US']) [1] birincisini alır.
Kevin Driedger

3
@KevinDriedger /bookstore/book[@location='US'][1]tüm kitapları 'ABD'den döndürmez. Bunu farklı zamanlarda ve farklı dillerin xpath uygulamaları altında test ettim. /bookstore/book[@location='US'][1]kitapçı altındaki ilk 'ABD' kitabını döndürür. Birden fazla kitapçı varsa, her birini ilkinden döndürür. Bu OP'nin istediği şey (kitapçı altındaki ilk düğüm). Sürümünüz tüm kitapçılardan yalnızca bir kitap döndürüyor (ilk eşleşme).
Jonathan Fingland

3
@JonathanFingland yanlış anladınız - AlexanderD.Ilyin'in sorusunun bağlamıyla birlikte KevinDriedger'in cevabını tekrar okuyun. İkiniz de aynı şeyi kastediyorsunuz.
kiedysktos

175

/bookstore/book[@location='US'][1] sadece basit yapı ile çalışır.

Biraz daha yapı ekleyin ve işler bozun.

İle

<bookstore>
 <category>
  <book location="US">A1</book>
  <book location="FIN">A2</book>
 </category>
 <category>
  <book location="FIN">B1</book>
  <book location="US">B2</book>
 </category>
</bookstore> 

/bookstore/category/book[@location='US'][1] verim

<book location="US">A1</book>
<book location="US">B2</book>

"daha karmaşık bir koşulla eşleşen ilk düğüm" değil. /bookstore/category/book[@location='US'][2]hiçbir şey döndürmez.

Parantezler ile orijinal sorunun şunun sonucunu elde edebilirsiniz:

(/bookstore/category/book[@location='US'])[1] verir

<book location="US">A1</book>

ve (/bookstore/category/book[@location='US'])[2]beklendiği gibi çalışır.


11
Burada kabul edilen cevabın yazarı. OP sorusu dikkate alındı /bookstore/book[1]ve DEĞİL (/bookstore/book)[1]. Sağladığınız durum OP'nin istediği ile aynı değil. Muhtemelen, OP beklediğim (ve istediği) gibi cevabımı kabul etti.
Jonathan Fingland

Bu cevap bana bu tuhaf dava için yardımcı oldu. Birisi neden "daha karmaşık durumları" ele almayacağını açıklayabilir mi? Temelde iki öğe içeren bir liste bulduğu için, [2] sadece onu almalı (benim
dünyamda

Ben de bu cevabı seçilen cevaptan daha doğru buluyorum, çünkü benim durumumda, [1] eklemenin birden fazla düğüm döndürdüğü daha karmaşık bir yapıya sahiptim. Teşekkürler!
mydoghasworms

2
Parantez çalışıyor! Ayrıca sonra daha yolunu ekleyebilir (..) [1], gibi: '(//div[text() = "'+ name +'"])[1]/following-sibling::*/div/text()'. Çok sayıda düğüm eşleşmesi olması durumunda name.
Hlung

1
Fikrimi değiştiriyorum. Bir süre sonra bu cevabın söylediklerini alıyorum ve OP'nin örneğini görmezsem buna oy verdim. Sanırım bu cevabın tonuna tepki veriyordum; @ tkurki durumu ilk düğüm seçiminden ayırma konusunda biraz daha açıklamış olsaydı, anında gördüm. JonFingland için de aynı şey geçerli.
Gerard ONeill

51

Jonathan Fingland'ın cevabına bir açıklama olarak:

  • aynı yüklem ( [position()=1 and @location='US']) içindeki birden çok koşul bir bütün olarak doğru olmalıdır
  • ardışık yüklemlerde birden çok koşul ( [position()=1][@location='US']) birbiri ardına doğru olmalı
  • bu [position()=1][@location='US']! = [@location='US'][position()=1]
    while [position()=1 and @location='US']== anlamına gelir[@location='US' and position()=1]
  • ipucu: bir yalnız [position()=1]kısaltmak[1]

Sen Boole operatörleri "ile yüklemler karmaşık ifadeler de oluşturabilirsiniz and" ve " or" ve Boole XPath fonksiyonları ile not(), true()ve false(). Ayrıca alt ifadeleri parantez içine alabilirsiniz.


15

İlk İngilizce kitap düğümünü (tüm belgede) bulmanın en kolay yolu, daha karmaşık yapılandırılmış xml dosyasını dikkate alarak:

<bookstore>
 <category>
  <book location="US">A1</book>
  <book location="FIN">A2</book>
 </category>
 <category>
  <book location="FIN">B1</book>
  <book location="US">B2</book>
 </category>
</bookstore> 

xpath ifadesi:

/descendant::book[@location='US'][1]


10
    <bookstore>
     <book location="US">A1</book>
     <category>
      <book location="US">B1</book>
      <book location="FIN">B2</book>
     </category>
     <section>
      <book location="FIN">C1</book>
      <book location="US">C2</book>
     </section>
    </bookstore> 

Yukarıda verilenler göz önüne alındığında; ile ilk kitabı seçebilirsiniz

(//book[@location='US'])[1]

Ve bu, ABD'nin bulunduğu her yerde ilkini bulacaktır. [A1]

//book[@location='US']

Düğüm kümesi konumu ABD ile tüm kitaplarla dönecekti. [A1, B1, C2]

(//category/book[@location='US'])[1]

Belgenin herhangi bir yerinde bir kategoride bulunan ilk kitap konumunu ABD dönecekti. [B1]

(/bookstore//book[@location='US'])[1]

kitapçığın kök öğesinin altında herhangi bir yerde bulunan ilk konumu ABD'ye döndürür; / kitapçı kısmını gerçekten gereksiz kılıyor. [A1]

Doğrudan cevapta:

/bookstore/book[@location='US'][1]

ABD'de kitapçı altında bulunan kitap öğesi için ilk düğümü döndürür [A1]

Bu arada, bu örnekte, doğrudan bir kitapçı çocuğu olmayan ilk ABD kitabını bulmak için:

(/bookstore/*//book[@location='US'])[1]

4

Xpath karmaşıksa veya aynı xpath ile birden fazla düğüm varsa, istenen düğümü almak için dizini kullanın.

Örn:

(//bookstore[@location = 'US'])[index]

Hangi düğümü istediğiniz numarayı verebilirsiniz.


2

verilen xml'de ad alanı sağlanmışsa, bunu kullanmak daha iyidir.

(/*[local-name() ='bookstore']/*[local-name()='book'][@location='US'])[1]


-1

Çevrimiçi bir xpath test cihazı yardımıyla bu cevabı yazıyorum ... Bunun
için:

<table id="t2"><tbody>
<tr><td>123</td><td>other</td></tr>
<tr><td>foo</td><td>columns</td></tr>
<tr><td>bar</td><td>are</td></tr>
<tr><td>xyz</td><td>ignored</td></tr>
</tbody></table>

aşağıdaki xpath:

id("t2") / tbody / tr / td[1]

çıktılar:

123
foo
bar
xyz

Yana 1 yollarla tümünü seçmek td kendi direkt ebeveynin ilk çocuğu olan unsurlar.
Ama aşağıdaki xpath:

(id("t2") / tbody / tr / td)[1]

çıktılar:

123
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.