วิธีการเลือกโหนดโดยใช้ XPath ถ้าโหนดพี่น้องมีค่าเฉพาะ?


89

ฉันมีเอกสารดังต่อไปนี้:

<a>
  <bb>abc</bb>
  <cc>ccc</cc>
  <dd>ddd</dd>
</a>
<a>
  <bb>zz</bb>
  <cc>1</cc>
  <dd>2</dd>
</a>

ฉันจะได้รับความคุ้มค่าของ<cc>การใช้ XPath ถ้า<bb>เป็นzz?


1
ปัญหาคือฉันรู้วิธีเข้าถึงโหนดเฉพาะ แต่ฉันไม่รู้ว่าจะเข้าถึงโหนดได้อย่างไรหากพี่น้องมีค่าเฉพาะ มันเป็นแบบนี้ได้ไหม / a / cc / contains (/ a / bb = 'zz')?
HOE SENGKIANG

คำตอบ:


101

ไม่แน่ใจว่าทำไมทุกคนถึงถามหาพี่น้องคุณยังสามารถตรวจสอบ<bb/>-elements ที่ตรงกับเพรดิเคตจากเพรดิเคต<a/>:

//a[bb/text() = "zz"]/cc/text()

24
"ไม่แน่ใจว่าทำไมทุกคนถึงถามหาพี่น้อง" : บางทีอาจเป็นเพราะคำถามสำหรับพี่น้อง .. ;-)
hr_117

4
ดูเหมือนว่าฉันไม่ได้อ่านชื่อเรื่องจริงๆ :) คำตอบยังคงใช้ได้อยู่ดี
Jens Erat

2
คำถามคำตอบของคุณสำหรับพี่น้องด้วย คุณไม่ได้ใช้*-siblingแกน +1 แม้ว่า
LarsH

นี่ไม่ได้ตอบคำถาม แต่ตอบคำถามจริงของฉันที่ฉันคิดสูตรไม่ดี ขอขอบคุณ!
User9213

37

สิ่งที่คุณต้องการคือfollowing-siblingแกน XPath

//a/bb[text()="zz"]/following-sibling::cc[1]/text()

ทดสอบ Xpath ที่นี่: http://www.xpathtester.com/obj/b55ec3ac-dfa4-4f44-81e8-f963ea4a0625


4
@HOESENGKIANG: คุณควรคลิกเครื่องหมายถูกเพื่อ "ยอมรับ" คำตอบนี้หรือข้อใดที่คุณคิดว่าตอบคำถามได้ดีที่สุด
LarsH

24

ถาม: จะเลือกโหนดโดยใช้ XPath ได้อย่างไรหากโหนดพี่น้องมีค่าเฉพาะ
เนื่องจากมีเพียง "แกน XPath" สำหรับการติดตามพี่น้องและก่อนหน้านี้คุณสามารถใช้หนึ่งในนั้นได้หากตำแหน่งได้รับการแก้ไข

แต่ดีกว่า: มองหาccว่าพ่อแม่มีลูกbbด้วยค่า'zz':

//cc[../bb='zz']

6
อย่างใดอย่างหนึ่งหรือ//a[bb = 'zz']/cc.
Tomalak

ไม่แน่ใจว่าคุณหมายถึงอะไรโดย "เฉพาะ" แกน XPath "สำหรับการติดตามพี่น้องและพี่น้องก่อนหน้า" คุณกำลังอ้างถึงข้อเท็จจริงที่ว่าไม่มีแกนเดียวสำหรับพี่น้องทั้งหมดหรือไม่?
LarsH

@ LarsH: ใช่ขอโทษ (ขอโทษภาษาอังกฤษที่ไม่ดีของฉัน :-() - นั่นคือสิ่งที่ฉันพยายามจะพูด (เพราะคำถามเป็นของพี่น้อง)
hr_117

6

ก่อนอื่นตัวอย่างของคุณไม่ใช่ XML ที่มีรูปแบบที่ดี เมื่อมองข้ามสิ่งนั้นและคุณไม่ได้อธิบายเจตนาของคุณได้เป็นอย่างดี (คุณต้องการเลือกเงื่อนไขใดกันแน่?) ฉันคิดว่าคุณต้องการทำสิ่งนี้:

//cc[preceding-sibling::bb[text()="zz"]]/text()

มันเลือก

TEXT VALUES OF ALL <CC> ELEMENTS
//cc                                    /text()
    THAT HAVE A PRECEDING SIBLING <BB>
    [preceding-sibling::bb             ]
                          THAT HAS TEXT VALUE EQUAL TO "zz"
                          [text()="zz"]

คุณสามารถเขียนได้เช่นกัน

//bb[text()="zz"]/following-sibling::cc/text()

โปรดดูข้อมูลจำเพาะมีตัวอย่างที่อ่านได้ดีซึ่งคุณจะได้เรียนรู้มากมาย


1
@LarsH ขอบคุณสำหรับการแก้ไขจาก "ไม่ถูกต้อง" เป็น "รูปแบบไม่ถูกต้อง" ฉันได้เรียนรู้สิ่งใหม่ ๆ ในวันนี้
Petr Janeček

4
//a/cc[../bb='zz']/text()

// a: เลือกองค์ประกอบ "a" ทั้งหมดไม่ว่าจะอยู่ที่ใด

// a / cc: เลือกองค์ประกอบ "cc" ที่เป็นลูกขององค์ประกอบ "a" (ไม่ว่า a จะอยู่ที่ใด)

.. : เลือกพาเรนต์ของโหนดปัจจุบัน

[../bb='zz ']: โดยที่ค่าขององค์ประกอบ' bb 'พี่น้องคือ zz

อ้างอิง: http://www.w3schools.com/xsl/xpath_syntax.asp


4

อีกวิธีหนึ่งสำหรับปัญหานี้คือ

//bb[contains(.,'zz')]/../cc/text()

คำอธิบาย : bbสิ่งที่มี'zz'สตริงในโหนดลูกทั้งหมดจากbbนั้นไปที่โหนดแม่ของการbbใช้..นั้นตอนนี้เราสามารถเข้าถึงccข้อความที่ส่งคืนได้

ฉันหวังว่าคำอธิบายจะไม่ซับซ้อน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.