Alt düğümün bir öznitelik içerdiği düğümleri alın


116

Aşağıdaki XML'e sahip olduğumu varsayalım:

<book category="CLASSICS">
  <title lang="it">Purgatorio</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

<book category="CLASSICS">
  <title lang="it">Inferno</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

<book category="CHILDREN">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

<book category="WEB">
  <title lang="en">XQuery Kick Start</title>
  <author>James McGovern</author>
  <author>Per Bothner</author>
  <author>Kurt Cagle</author>
  <author>James Linn</author>
  <author>Vaidyanathan Nagarajan</author>
  <year>2003</year>
  <price>49.99</price>
</book>

<book category="WEB">
  <title lang="en">Learning XML</title>
  <author>Erik T. Ray</author>
  <year>2003</year>
  <price>39.95</price>
</book>

"İt" dil özniteliğine sahip bir başlık düğümüne sahip tüm kitap düğümlerini geri alan bir xpath yapmak istiyorum.

Benim girişimim şuna benziyordu:

//book[title[@lang='it']]

Ama bu işe yaramadı. Düğümleri geri almayı bekliyorum:

<book category="CLASSICS">
  <title lang="it">Purgatorio</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

<book category="CLASSICS">
  <title lang="it">Inferno</title>
  <author>Dante Alighieri</author>
  <year>1308</year>
  <price>30.00</price>
</book>

Herhangi bir ipucu?


Bu hangi XPath uygulamasıdır?
Pavel Minaev

Yanıtlar:


175

Deneyin

//book[title/@lang = 'it']

Bu okur:

  • tüm bookunsurları al
    • en az bir tane var title
      • bir niteliği olan lang
        • değeri ile "it"

Sen bulabilir bu yararlı - bu başlıklı bir makale "Beş paragraflarda XPath" Ronald Bourret tarafından.

Ancak dürüst olmak gerekirse //book[title[@lang='it']]ve XPath motorunuzda "sorunlar" olmadığı sürece yukarıdakiler eşdeğer olmalıdır. Dolayısıyla, bize göstermediğiniz kodda veya örnek XML'de bir şey olabilir - örneğin, örneğiniz bir XML parçasıdır. Kök öğenin bir ad alanı olabilir ve sorgunuzda bunu saymıyor musunuz? Ve bize sadece işe yaramadığını söyledin, ama bize hangi sonuçları aldığını söylemedin.


4
titleDoğrudan çocuğu değilse de book, daha derin bir yerde ve tam olarak nerede olduğunu bilmiyorsak , aynı şeyi nasıl yapabiliriz ? //book[/title/@lang = 'it']işe yaramıyor gibi görünüyor?
Martin Konicek

5
Martin, //book[.//title/@lang = 'it'] kullanabilirsiniz. Numaranın "" olduğuna inanıyorum. Durumun başında.
Bruno Caponi

1
Bağlantı için teşekkürler, mükemmel makale. Yıllardır xPath kullanıyorum ama bu, temeldeki mantığı anlamama gerçekten yardımcı oldu!
swensor

57

Yıllar sonra, ancak yararlı bir seçenek XPath Axes'ı kullanmak olacaktır ( https://www.w3schools.com/xml/xpath_axes.asp ). Daha spesifik olarak, torun eksenlerini kullanmak istiyorsunuz .

Bu örneğin işe yarayacağına inanıyorum:

//book[descendant::title[@lang='it']]

Bu, "it" e eşit dil özniteliği değeri bookiçeren bir alt titleöğe içeren (ne kadar derinlemesine yerleştirildiğine bakılmaksızın) tüm öğeleri seçmenize olanak tanır .

Bu cevabın 2009 yılıyla ilgili olup olmadığını kesin olarak söyleyemem çünkü o sırada XPath Eksenlerinin var olduğundan% 100 emin değilim. Doğrulayabileceğim şey, bugün var oldukları ve onları XPath navigasyonunda son derece yararlı bulduğum ve sizin de yapacağınıza eminim.


12
//book[title[@lang='it']]

aslında eşdeğerdir

 //book[title/@lang = 'it']

Vtd-xml kullanarak denedim, her iki ifade de aynı sonucu verdi ... Hangi xpath işleme motorunu kullandınız? Sanırım uyum sorunu var Aşağıda kod var

import com.ximpleware.*;
public class test1 {
  public static void main(String[] s) throws Exception{
      VTDGen vg = new VTDGen();
      if (vg.parseFile("c:/books.xml", true)){
          VTDNav vn = vg.getNav();
          AutoPilot ap = new AutoPilot(vn);
          ap.selectXPath("//book[title[@lang='it']]");
                  //ap.selectXPath("//book[title/@lang='it']");

          int i;
          while((i=ap.evalXPath())!=-1){
              System.out.println("index ==>"+i);
          }
          /*if (vn.endsWith(i, "< test")){
             System.out.println(" good ");  
          }else
              System.out.println(" bad ");*/

      }
  }
}

Bunun bir uyumluluk sorunu olduğunu ve sözdiziminin aynı düğüm kümesini oluşturduğunu +1. C #'daki benzer kod da çalışır.
Zach Bonham

-1: Bay Zhang, soruyla ilgisi olmayan kodu kaldırarak size bir iyilik yapmaya çalışıyordum. Sana olumsuz oy vermememe izin verdi, ki şimdi buna mecbur hissediyorum. Sorguyu çağırmak için başka hiçbir yanıtın kod içermediğini unutmayın.
John Saunders

6
+1: Çünkü Bay Saunders'ın ne hakkında konuştuğunu anlayamıyorum - başka hiçbir cevap HİÇBİR kod eklemedi ve bu cevap kullanılan kodu gösteriyor, böylece 1: yöntemlerini doğrulayabilir ve 2: testini kendimiz gerçekleştirebiliriz. Kod kısa ve okunması kolay. Sorunu görmüyorum.
DuckPuppy

4

Kendi önerinizin doğru olduğunu düşünürdüm, ancak xml tam olarak geçerli değil. Eğer çalışıyorsa //book[title[@lang='it']]üzerine <root>[Your"XML"Here]</root>daha sonra ücretsiz çevrimiçi xPath test gibi bir buraya beklenen sonucu bulacaksınız.


2

Bu xPath ifadesini kullanmayı deneyin:

//book/title[@lang='it']/..

Bu size tüm kitap düğümlerini "it" dilinde vermelidir


2
bu ifadenin sonucu kitap düğümleri değil, başlık düğümleridir
Caleth

2
Bu doğru değil. Kitap düğümlerini döndürür (sondaki bu iki nokta, başlık düğümünün üst düğümünü hedefler).
user1113000
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.