2010-11-29 20 views
7

मान लें कि मैं एक xhtml दस्तावेज़ से पूछताछ कर रहा हूं, और मैं id='target' वाली तालिका के बाद सभी भाई बहनों से पूछताछ करना चाहता हूं। इसके अलावा, मैं न तो पहले <table> भाई और न ही इस विशेष तत्व के पहले <ol> भाई को चाहता हूं। यहां सबसे अच्छा है जिसके साथ मैं आ सकता हूं:XPath - पहले विशिष्ट तत्वों को छोड़कर सभी निम्नलिखित भाई बहन

//table[@id='target']/following-sibling::*[not(self::table[1]) and not(self::ol[1])] 

हालांकि, यह किसी भी परिणाम को वापस नहीं कर रहा है जब यह चाहिए। जाहिर है, मैं इसके लिए कुछ वाक्यविन्यास को समझ नहीं रहा हूं (मुझे जानकारी का अच्छा स्रोत नहीं मिला)। अगर मैं XPath सिंटैक्स के साथ अधिक अनुभव करता हूं तो मैं निश्चित रूप से इसकी सराहना करता हूं। इसके अलावा, पूरी तरह अकादमिक उद्देश्यों के लिए, मैं उत्सुक हूं कि उपर्युक्त वास्तव में क्या कर रहा है।

अद्यतन:
मेरी XPath क्यों काम नहीं कर रहा था, इसके स्पष्टीकरण के लिए लार्सएच का जवाब देखें, और स्वीकृत समाधान के लिए दिमित्री का जवाब देखें।

+0

अच्छा सवाल, +1। एक एक्सपीएथ अभिव्यक्ति के लिए मेरा उत्तर देखें जो बिल्कुल वांछित नोड्स का चयन करता है। :) –

उत्तर

10

उपयोग:

/table[@id='target']/following-sibling::*[not(self::table) and not(self::ol)] 
| 
/table[@id='target']/following-sibling::table[position() > 1] 
| 
/table[@id='target']/following-sibling::ol[position() > 1] 

यह है कि table नहीं हैं और ol और स्थिति 2 या अधिक से अधिक और के साथ सभी निम्नलिखित ol भाई बहनों के साथ सभी निम्नलिखित table भाई बहन नहीं हैं तालिका निम्न में से सभी भाई बहन का चयन करता है स्थिति 2 या अधिक।

है कौन वास्तव में क्या आप हैं: भाई और पहली ol निम्नलिखित भाई बहन के बाद पहले table के अपवाद के साथ सभी निम्नलिखित भाई बहन।

यह शुद्ध XPath 1.0 है और किसी भी XSLT फ़ंक्शंस का उपयोग नहीं कर रहा है।

+1

यह वास्तव में एक शानदार समाधान है जिसे मैं ढूंढ रहा था, और यह वास्तव में काफी सरल है। यह उन तीन तत्वों को छोड़कर सब कुछ युक्त तीन परस्पर अनन्य सेटों का संघ प्राप्त करने के लिए कभी नहीं हुआ। धन्यवाद! – Shaun

+0

@ शुन: आपका स्वागत है। –

+0

आह, इसके बारे में सोचना चाहिए था। :-) मैं एक संघ समाधान की कोशिश कर रहा था लेकिन इसे प्राप्त नहीं कर सका। टाइपो हालांकि: मूल प्रश्न के अनुसार, 'table' से पहले' // 'की बजाय' // 'की आवश्यकता है। – LarsH

1

जब आप self:: धुरी का उपयोग करते हैं तो केवल एक नोड होने जा रहा है, इसलिए मेरा मानना ​​है कि self::*[1] हमेशा सत्य होगा। प्रत्येक नोड अपने स्वयं के self:: धुरी पर पहला (और केवल) नोड होगा। इसका मतलब है कि आपकी ब्रैकेटेड अभिव्यक्ति [not(self::table) and not(self::ol)] के बराबर है, जिसका अर्थ है कि सभी तालिकाओं और सूचियों को फ़िल्टर किया जाता है।

मैं एक परीक्षण वातावरण की स्थापना की जरूरत नहीं है, लेकिन मेरे सिर के ऊपर से यह कर सकता है बेहतर:

/table[@id='target']/following-sibling::* 
    [not(self::table and not(preceding-sibling::table)) and 
    not(self::ol and not(preceding-sibling::ol))] 

यह कुछ फेरबदल की आवश्यकता होगी, लेकिन यह विचार को फ़िल्टर करने के table रों है जिसमें पिछले-भाई table एस, और ol एस नहीं हैं जो पिछले-भाई ol एस नहीं हैं।

+0

जैसा कि मैंने अपने उत्तर में उल्लेख किया है, यह समाधान इस तथ्य को याद करता है कि लक्ष्य तालिका को पिछले भाई-बहन के रूप में नहीं माना जाना चाहिए जब आप भाई बहनों के बाद परीक्षण कर रहे हैं कि यह देखने के लिए '[1] 'है। साथ ही, किसी भी तालिका या ओएल तत्व * लक्ष्य तालिका से पहले * पिछले-भाई परीक्षण द्वारा अनदेखा किया जाना चाहिए। – LarsH

2

पहले दूसरे प्रश्न का उत्तर दें: उपरोक्त क्या है, निम्नलिखित सभी भाई बहनों का चयन करना है जो न तो table और न ही ol तत्व हैं। self::table[1] संदर्भ नोड के आत्म का चयन करता है (आईएफएफ यह table तत्व नाम परीक्षण में सफ़ल) और फिल्टर स्वयं :: अक्ष के साथ ही प्रथम नोड का चयन करने के:

यहां इसका कारण बताया। स्वयं :: अक्ष पर तत्व पर सबसे अधिक एक नोड तत्व नाम परीक्षण पास कर रहा है, इसलिए [1] अनावश्यक है। self::table[1] अपने भाई बहनों के बीच अपनी स्थिति के बावजूद, जब भी यह तालिका तत्व है, संदर्भ नोड का चयन करता है। तो not(self::table[1]) भाषण देता है जब भी संदर्भ नोड एक तालिका तत्व होता है, भले ही भाई बहनों के बीच इसकी स्थिति हो।

इसी प्रकार self::ol[1] के लिए।

आप जो करने की कोशिश कर रहे हैं, उसे कैसे करें: @ जॉन कुगेलमैन का जवाब लगभग सही है, लेकिन इस तथ्य को याद करते हैं कि हमें table[@id='target'] से पहले और भाई तत्वों को अनदेखा करना होगा। मुझे नहीं लगता कि शुद्ध XPath 1.0 में सही ढंग से करना संभव है। क्या आपके पास XPath 2.0 का उपयोग करने की संभावना है? यदि आप किसी ब्राउज़र में काम कर रहे हैं, तो उत्तर आम तौर पर नहीं होता है।

कुछ समाधान होगा:

  • पहले निम्न तालिका भाई और कुछ अन्य आधार पर छान कर पहले निम्नलिखित ol भाई जाएं, इस तरह उनकी विशेषताओं के रूप में;
  • //table[@id='target'] को नोडसेट के रूप में चुनें, इसे होस्ट वातावरण में वापस करें (यानी XPath के बाहर, उदा।जावास्क्रिप्ट में), उस नोडसेट के माध्यम से लूप; लूप के अंदर: XPath के माध्यम से following-sibling::* का चयन करें, के माध्यम से XPath के बाहर, और प्रत्येक परिणाम (XPath के बाहर) का परीक्षण करने के लिए यह जांचें कि यह पहली तालिका या ओएल है या नहीं।
  • //table[@id='target'] को नोडसेट के रूप में चुनें, इसे होस्ट वातावरण (यानी XPath के बाहर, उदाहरण के लिए जावास्क्रिप्ट में) पर लौटें, उस नोडसेट के माध्यम से लूप; लूप के अंदर: XPath के माध्यम से generate-id(following-sibling::table[1]) और generate-id(following-sibling::ol[1]) का चयन करें, उन मानों को जेएस वेरिएबल्स t1id और o1id में प्राप्त करें, और 'following-sibling::*[generate-id() != ' + t1id + ' and generate-id() != ' + o1id + ']' फ़ॉर्म का उपयोग करके XPath अभिव्यक्ति के लिए एक स्ट्रिंग बनाएं। XPath में उस स्ट्रिंग का चयन करें और आपका जवाब है! :-P

अद्यतन: एक समाधान XSLT 1.0 में संभव है - @ Dimitre देखते हैं।

+0

@ जॉन कुगेलमैन: शुद्ध और जटिल जटिल XPath 1.0 समाधान के लिए मेरे एमएसवर पर नज़र डालें। –

+0

मेरी व्याख्या की गई क्वेरी विफल होने के कारण महान स्पष्टीकरण के लिए धन्यवाद। मैं अंततः समस्या को हल करने के लिए दिमित्री के XPath के साथ चला गया। – Shaun

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