2012-10-13 14 views
25

इस तरह देखते हुए मार्कअप:क्या XPath क्वेरी परिणाम के पैरेंट नोड प्राप्त करने का कोई बेहतर तरीका है?

<div class="foo"> 
    <div><span class="a1"></span><a href="...">...</a></div> 
    <div><span class="a2"></span><a href="...">...</a></div> 
    <div><span class="a1"></span>some text</div> 
    <div><span class="a3"></span>some text</div> 
</div> 

अब मैं इन <a> और some text प्राप्त करने में दिलचस्पी केवल यदि आसन्न span वर्ग a1 की है। तो पूरे कोड के अंत में मेरा परिणाम <a> पहले div और some text से तीसरे स्थान पर है। यह आसान होगा अगर <a> और some textspan या div के अंदर class विशेषता होगी, लेकिन कोई भाग्य नहीं होगा।

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')] 

और उसके बाद अपनी मूल हो और संदर्भ नोड के रूप में है कि माता-पिता नोड के साथ एक और query() कार्य करें:

क्या मैं अब कर रहा हूँ spana1 इस तरह वर्ग के साथ के लिए क्वेरी है। यह बहुत कुशल होने की तरह दिखता है तो क्या ऐसा करने का कोई बेहतर तरीका है?


उत्तर

प्रति @MarcB answer के रूप में, सही क्वेरी है:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/.. 

लेकिन <A> के लिए उपयोग करने के लिए बेहतर हो सकता है:

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/../a 

<A> में प्राप्त करें इसके कंटेनर की स्थिरता।

उत्तर

54

xpath क्वेरी के बारे में अच्छी बात यह है कि आप अनिवार्य रूप से उन्हें एक फ़ाइल सिस्टम पथ की तरह व्यवहार कर सकते हैं, तो बस

//div[contains(@class,'foo')]/div/span[contains(@class,'a1')]/.. 
                   ^^ 

होने अपने सभी .a1 नोड्स कि एक .foo नोड नीचे हैं मिलेगा है, तो इस कदम ए 1 नोड्स के माता-पिता के लिए एक स्तर ऊपर।

+4

प्रणाली रास्तों दायर करने के लिए संदर्भ के लिए +1, कि मैं कैसे नहीं हुआ है हमेशा इसके बारे में सोचा लेकिन मैंने इसे कभी भी –

+1

के रूप में समझाया नहीं है मैंने सवाल पूछने से पहले मैन्युअल की जांच की लेकिन ऐसा लगता है कि मैं ".." याद करने में कामयाब रहा क्योंकि यह स्पष्ट रूप से वहां है। लेकिन एफएस संदर्भ ने इसे तुरंत स्पष्ट कर दिया। धन्यवाद। –

+1

हाँ। जब मैं पहली बार xpath में कूद गया, तो मैं थोड़ी देर के लिए इस तरह घूमता था, लेकिन क्वेरी <-> पथ संघ बनाना मेरे लिए काफी यूरेका क्षण था। –

16

एक अभिव्यक्ति है कि बेहतर रिवर्स अक्ष का उपयोग करने से है:

//div[contains(@class,'foo')]/div[span[contains(@class,'a1')]] 

यह किसी भी div कि एक div जिसका class विशेषता का एक बच्चा है का चयन करता स्ट्रिंग "foo" होता है और कि (चयनित div) में span बच्चा है जिसका class विशेषता स्ट्रिंग "ए 1" है।

XSLT - आधारित सत्यापन:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "//div[contains(@class,'foo')] 
      /div[span[contains(@class,'a1')]]"/> 
</xsl:template> 
</xsl:stylesheet> 

जब इस बदलाव प्रदान की XML दस्तावेज़ पर भी लागू होता है:

<div class="foo"> 
    <div><span class="a1"></span><a href="...">...</a></div> 
    <div><span class="a2"></span><a href="...">...</a></div> 
    <div><span class="a1"></span>some text</div> 
    <div><span class="a3"></span>some text</div> 
</div> 

XPath अभिव्यक्ति मूल्यांकन किया जाता है और चयनित तत्वों कॉपी कर रहे हैं आउटपुट में:

<div> 
    <span class="a1"/> 
    <a href="...">...</a> 
</div> 
<div> 
    <span class="a1"/>some text</div> 

II। इसकी कक्षाएं में से एक ने किसी HTML तत्व तक पहुंचने से संबंधित टिप्पणी:

यह जाना जाता है तत्व केवल एक ही वर्ग हो सकता है, तो यह आवश्यक नहीं है सब पर उपयोग करने के लिए

का प्रयोग न करें है:

//div[contains(@class, 'foo')] 

उपयोग:

//div[@class = 'foo'] 

या, अगर वहाँ प्रमुख/रिक्त स्थान अनुगामी हो सकता है, का उपयोग करें:

//div[normalize-space(@class) = 'foo'] 

के साथ एक महत्वपूर्ण मुद्दा:

//div[contains(@class, 'foo')] 

कि इस वर्ग के साथ किसी भी div का चयन करता है इस तरह के "myfoo" के रूप में है , "foo2" या "myfoo3"।

तत्व एक से अधिक वर्ग हो सकता है, और इसके बाद के संस्करण मुद्दे से बचने के लिए करते हैं, तो सही XPath अभिव्यक्ति है:

//div[contains(concat(' ', @class, ' '), ' foo ')] 
+2

यह मत भूलना एचटीएमएल कई कक्षाओं की अनुमति देता है। '@ class = 'foo'' वर्ग = "foo bar baz" पर छोड़ देगा। इस तरह, @contains पूरी तरह से मान्य है, जैसा कि आप (जैसा कि आप इंगित करते हैं), आप झूठी सकारात्मक –

+3

@MarcB के लिए देखते हैं, ऐसा लगता है कि आपने इस उत्तर को पढ़ या समझ नहीं लिया है - यह उस मामले की लंबाई में व्यवहार करता है जहां एक तत्व एक से अधिक वर्ग है। इसके अलावा, यह उत्तर उस मामले के लिए एक सही समाधान प्रदान करता है - गलत और सरल 'जैसे नहीं (@calss, someString) –

संबंधित मुद्दे