2010-04-11 25 views
43

पर XPath चलाना मैं xpath लुकअप द्वारा लौटाए गए नोड्स पर एक एक्सपैथ लुकअप करने की कोशिश कर रहा हूं, लेकिन ऐसा लगता है कि यह अपेक्षित काम नहीं करता है। दस्तावेज़ के बच्चे नोड्स पर निष्पादित एक्सपैथ के खिलाफ निष्पादित किया गया प्रतीत होता है दस्तावेज के रूट रूट नोड (उदाहरण में, इन्वेंट्री टैग।), प्रदान किए गए नोड की जड़ के बजाय।बच्चे नोड

क्या मुझे यहां कुछ याद आ रही है? मैं XPath के लिए नया हूँ।

इसके अलावा, कृपया "बस // पुस्तक [लेखक = 'नील स्टीफनसन'/शीर्षक" का उत्तर न दें। मेरे पास वैध उपयोग केस है, और यह एक सरल उदाहरण है।

कोड स्निपेट

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); 
domFactory.setNamespaceAware(true); 
DocumentBuilder builder = domFactory.newDocumentBuilder(); 
Document doc = builder.parse("src/main/java/books.xml"); 

XPathFactory factory = XPathFactory.newInstance(); 
XPath xpath = factory.newXPath(); 

Node book = (Node) xpath.evaluate("//book[author='Neal Stephenson']", doc, XPathConstants.NODE); 
Node title = (Node) xpath.evaluate("/title", book, XPathConstants.NODE); // I get null here. 
Node inventory = (Node) xpath.evaluate("/inventory", book, XPathConstants.NODE); // this returns a node. 

book.xml

<inventory> 
<book year="2000"> 
    <title>Snow Crash</title> 
    <author>Neal Stephenson</author> 
    <publisher>Spectra</publisher> 
    <isbn>0553380958</isbn> 
    <price>14.95</price> 
</book> 

<book year="2005"> 
    <title>Burning Tower</title> 
    <author>Larry Niven</author> 
    <author>Jerry Pournelle</author> 
    <publisher>Pocket</publisher> 
    <isbn>0743416910</isbn> 
    <price>5.99</price> 
</book> 

<book year="1995"> 
    <title>Zodiac</title> 
    <author>Neal Stephenson</author> 
    <publisher>Spectra</publisher> 
    <isbn>0553573862</isbn> 
    <price>7.50</price> 
</book> 

<!-- more books... --> 

</inventory> 
+1

अन्य लोगों ने आपके प्रश्न के अच्छे उत्तर दिए हैं। ध्यान दें कि '// बुक' और '//' से शुरू होने वाली अन्य अभिव्यक्ति प्रदर्शन को प्रभावित कर सकती हैं, क्योंकि संपूर्ण डोम पेड़ की खोज की जानी चाहिए। '/ सूची/पुस्तक' अधिक कुशल है। एक ही नोट पर, यदि एक XPath अभिव्यक्ति का उपयोग कई बार किया जा रहा है, तो आपको संभवतः 'XPath.compile()' के साथ इसे संकलित करना चाहिए और परिणामस्वरूप 'XPathExpression.evaluate()' को चलाने के बजाय, 'XPath को बार-बार कॉल करने की बजाय .evaluate() '। – markusk

+1

यहां उत्तर दिया गया: http://stackoverflow.com/questions/8358994/xpath-search-on-subtree – Benj

+0

यह जावा में न केवल इस तरह से काम करता है। .NET एक ही काम करता है। – ajeh

उत्तर

43

/foo रूट नोड के आधार पर चयन करेगा, इस संदर्भ को अनदेखा कर रहा है कि आप xpath के विरुद्ध मूल्यांकन कर रहे हैं। foo (स्लैश के बिना) जो आप चाहते हैं; जो वर्तमान नोड के आधार पर चयन करता है।

https://www.w3schools.com/xml/xpath_syntax.asp थोड़ा और जानकारी देता है।

+4

उस स्पष्टीकरण के लिए धन्यवाद। मैं w3schools से दूर रहूंगा जिसमें बहुत खराब सामग्री या अधिकांश एक्सएमएल विषय हैं। – MonoThreaded

+2

w3schools सीमित है और फोकस में कमी है, यकीन है, लेकिन यह बहुत ही सुलभ है। प्रौद्योगिकी की अच्छी बुनियादी व्याख्याओं में इंटरनेट की गंभीर कमी है। जबकि आपको और मुझे ऐसी चीज की आवश्यकता नहीं हो सकती है, वैसे भी w3schools कहीं और अधिक महत्वपूर्ण होने से पहले क्या कर रहे हैं, इसका एक अच्छा विचार पाने के लिए एक महान जगह है। – meustrus

+0

यदि मैं पुस्तक नोड का उपयोग करके "// book [@ year = '2000']/title" के साथ चाहता हूं तो क्या होगा? –

7

बस अपने सबक्वेरी के बंद अग्रणी स्लैश लेने के लिए और आप ठीक होना चाहिए। तो आप "//book" के माध्यम से अपनी पुस्तकें प्राप्त करते हैं, और उसके बाद बच्चे बिट्स प्राप्त करने के लिए यह केवल "title", "inventory" आदि है।

3

जावा कार्यान्वयन में वास्तव में अजीब बात यह है कि दस्तावेज़ से निकाला गया नोड अभी भी मूल दस्तावेज़ का संदर्भ देता है (Node.getOwnerDocument() देखें) और xpath रूट खोजने के लिए इसका उपयोग करता है।

अन्य ने xpath को वास्तव में को स्लैश को हटाकर रूट से शुरू करने का तरीका बताया है।

मुझे एक समान समस्या थी, लेकिन मैं चाहता था कि xpath रूट दस्तावेज़ों और बाल नोड्स (एक xpath के साथ /title) को संभालने के लिए चाहता था। समाधान क्लोन नोड: Node.cloneNode(true) था। true पैरामीटर पर ध्यान दें जो नोड को अपने मूल दस्तावेज़ को हिलाता है।

... अंत में, यह प्रदर्शन को बहुत अधिक नुकसान पहुंचाता है और नोड को संभालने के लिए अलग xpaths रखने और दस्तावेज़ को प्राथमिकता दी गई थी। X12ath में

+0

यदि प्रदर्शन कोई मुद्दा नहीं है, तो यह एक अच्छा समाधान है (या कामकाज ...)! – Ice09

+0

मुझे नहीं लगता कि यह जावा के लिए विशिष्ट है। मैंने जावा, पीएचपी और जावास्क्रिप्ट में डोम का उपयोग किया है, और सभी तीन भाषाओं में इंटरफ़ेस लगभग समान है, जिस तरह से नोड्स अपने माता-पिता दस्तावेज़ों को याद रखने के लिए जारी रखते हैं जब तक कि एक नए संदर्भ में क्लोन न किया जाए। – meustrus

19

"। (डॉट) वर्तमान दस्तावेज़ का प्रतिनिधित्व करता है। तो, "XP" के बाद अपना XPATH स्ट्रिंग लिखें। (डॉट)।

पूर्व:

"./title" 

या

".//title" 

तुम जो भी चाहते हैं ....

स्लैश को हटाने केवल तभी इसकी नोड का एक बच्चा काम करता है। यदि आप // (वर्तमान दस्तावेज़ में कहीं भी) कार्यक्षमता का उपयोग करना चाहते हैं तो क्या होगा?

तो, भी ऊपर जवाब के लिए डॉट का उपयोग (।)

धन्यवाद एक बहुत :)।

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