2010-01-29 8 views
34

यहां मेरे xml का एक अंश है:XPath: एक और भाई तक सभी भाई बहनों का चयन करें

<node/> 
<node/> 
<node id="1">content</node> 
<node/> 
<node/> 
<node/> 
<node id="2">content</node> 
<node/> 
<node/> 

मैं node[@id='1'] में स्थित हूं। मुझे सभी <node/> तत्वों से मिलान करने के लिए एक्सपैथ की आवश्यकता नहीं है जब तक कि अगले खाली नोड (यहां node[@id='2']) न हो।


संपादित करें: @id विशेषताएँ केवल मेरी समस्या को स्पष्ट रूप से समझाने के लिए हैं, लेकिन मेरे मूल XML में नहीं हैं। मुझे एक समाधान की आवश्यकता है जो @id विशेषताओं का उपयोग नहीं करता है।


मैं नहींnode[@id='2'] के बाद खाली भाई बहनों से मेल खाना चाहता हूं, इसलिए मैं एक बेवकूफ following-sibling::node[text()=''] का उपयोग नहीं कर सकता।

मैं इसे कैसे प्राप्त कर सकता हूं?

+0

भी देखें: http://stackoverflow.com/questions/2165566/xslt-select-following-sibling -एक-पहुंच-पहुंच-निर्दिष्ट-टैग – WBT

+0

यह उपयोग में हो सकता है: [http://stackoverflow.com/questions/2063619/how-to-reformat-xml-with-group-adjacent-xslt](http:/ /stackoverflow.com/questions/2063619/how-to-reformat-xml-with-group-adjacent-xslt) – igor

उत्तर

21

आप यह इस तरह से कर सकता है।

अभिव्यक्ति का कहना है:

    वर्तमान संदर्भ से
  • माता पिता
  • करने के लिए जाना उन बच्चे नोड्स
  • कोई पाठ और
  • सब से "पूर्ववर्ती
  • भाई नोड्स एक आईडी है कि राशि का चयन "पहले व्यक्ति के पास 1

यदि आप एक्सएसएलटी में हैं तो आप निम्न-भाई अक्ष से चुन सकते हैं एक कुंजी के साथ

<!-- the for-each is merely to switch the current node --> 
<xsl:for-each select="node[@id='1']"> 
    <xsl:copy-of select=" 
    following-sibling::node[ 
     not(text()) and 
     generate-id(preceding-sibling::node[@id][1]) 
     = 
     generate-id(current()) 
    ] 
    " /> 
</xsl:for-each> 

या सरल (और अधिक कुशल): ause आप current() समारोह का उपयोग कर सकते

<xsl:key 
    name="kNode" 
    match="node[not(text())]" 
    use="generate-id(preceding-sibling::node[@id][1])" 
/> 

<xsl:copy-of select="key('kNode', generate-id(node[@id='1']))" /> 
+0

अंततः मैं एक और मार्ग चला गया, क्योंकि मैं एक्सएसएलटी के बाहर हूं, इसलिए मैं निम्नलिखित सभी भाई नोड्स का चयन करता हूं, और उन पर फिर से शुरू करें, और जब मैं अगली नहीं सामना करता हूं तो मेरे लूप को रोक दें खाली। मैं आपके उत्तर को पूरी तरह से स्वीकार करता हूं, क्योंकि अब मुझे विश्वास है कि XPath में मैंने जो भी पूछा है, वह करने के लिए कोई भी लाइनर नहीं है। – glmxndr

+0

@subtenante: एर्म - लेकिन वहां * एक XPath एक-लाइनर है जो मेरे उत्तर में सही है ?! – Tomalak

+0

हां, आप सही हैं, मेरा प्रश्न वास्तव में इस तथ्य के बारे में स्पष्ट नहीं है कि मैंने जो आईडी विशेषताएं रखी हैं, वे केवल दिखाने और समस्या को समझाने के लिए थीं। मेरे पास वास्तव में मेरे एक्सएमएल में आईडी विशेषता नहीं है। – glmxndr

8

XPath 2.0 ऑपरेटरों < < 'और' >> 'जहां node1 << node2 है सही है अगर दस्तावेज़ 1 में node2 node2 से पहले है। तो एक XSLT में XPath 2.0 के साथ पर आधारित है कि 2.0 स्टाइलशीट जहां वर्तमान नोड नोड है [@id = '1'] क्या आप

following-sibling::node[not(text()) and . << current()/following-sibling::node[@od][1]] 

कि भी XSLT से वर्तमान() फ़ंक्शन की जरूरत है इस्तेमाल कर सकते हैं, इसलिए यही कारण है कि मैंने कहा "एक्सपीएलटी 2.0 स्टाइलशीट में XPath 2.0 के साथ"। उपरोक्त वाक्यविन्यास शुद्ध एक्सपीएथ है, एक एक्सएसएलटी स्टाइलशीट में आपको '< <' से बचने की आवश्यकता होगी '& लेफ्टिनेंट; & लेफ्टिनेंट; '।

8

स्वीकार किए जाते हैं जवाब से अधिक आसान:

//node[@id='1']/following-sibling::node[following::node[@id='2']] 
  • कहीं भी एक नोड जिसका आईडी '1'
  • है का पता लगाएं अब सभी निम्नलिखित भाई node तत्वों
  • लगता है ... लेकिन केवल उन अगर तत्वों के पास node भी id="2" उनके साथ कहीं भी है।

एक और अधिक स्पष्ट परीक्षण दस्तावेज़ (और कानूनी id मान) के साथ कार्रवाई में दिखाया गया:

xml = '<root> 
<node id="a"/><node id="b"/> 
<node id="c">content</node> 
<node id="d"/><node id="e"/><node id="f"/> 
<node id="g">content</node> 
<node id="h"/><node id="i"/> 
</root>' 

# A Ruby library that uses libxml2; http://nokogiri.org 
require 'nokogiri'; doc = Nokogiri::XML(xml) 

expression = "//node[@id='c']/following-sibling::node[following::node[@id='g']]" 
puts doc.xpath(expression) 
#=> <node id="d"/> 
#=> <node id="e"/> 
#=> <node id="f"/> 
+0

आपने यहां 'निम्नलिखित' अक्ष क्यों चुना है? यदि दस्तावेज़ बड़ा होता है तो यह झूठी सकारात्मक स्थिति को सड़क के नीचे दे सकता है (निम्नलिखित अक्ष के अलावा किसी भी अन्य धुरी की तुलना में धीमी गति से)। – Abel

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