दिलचस्प पोस्ट
नेट में "खुले सामान्य प्रकार" क्या है? मैं रिमोट जीआईटी शाखा कैसे बदलूंगा? आकार रंग गतिशील रूप से कैसे परिवर्तित करें? क्या बिना सी में एक पासवर्ड प्राप्त हो रहा है (3)? एक स्ट्रिंग को एक टेम्पलेट स्ट्रिंग में कनवर्ट करें मैं HTML <select> तत्व के लिए डिफ़ॉल्ट मान कैसे सेट कर सकता हूं? जीसीसी 4.x / C ++ 11 में refdounted std :: स्ट्रिंग है? गैर-विभाजन से विभाजित तालिकाओं में माइग्रेट करना क्लोन () विधि java.lang.Object में क्यों सुरक्षित है? सी # में Process.MainModule.FileName तक पहुँचने पर Win32 अपवाद से कैसे बचें? एनआईटी में एपीआई-तोड़ने वाले बदलावों के लिए एक निश्चित गाइड फ़ाइल पथ से जावा JTree निर्देशिका संरचना पैरामीटर के रूप में एक चर के प्रकार का उपयोग करके सी # में जेनरिक getCurrentPosition () और watchPosition () असुरक्षित मूल पर बहिष्कृत कर रहे हैं वाईएक्स इंस्टॉलर का उन्नयन कैसे लागू करें?

जावा में XPath के साथ namespaces का उपयोग करने के लिए XML क्वेरी कैसे करें?

जब मेरी XML इस तरह दिखती है (कोई xmlns नहीं है) तो मैं इसे XPath जैसे /workbook/sheets/sheet[1] तरह आसानी से पूछ सकता हूं

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <workbook> <sheets> <sheet name="Sheet1" sheetId="1" r:id="rId1"/> </sheets> </workbook> 

लेकिन जब ऐसा लगता है तो मैं नहीं कर सकता

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> <sheets> <sheet name="Sheet1" sheetId="1" r:id="rId1"/> </sheets> </workbook> 

कोई विचार?

वेब के समाधान से एकत्रित समाधान "जावा में XPath के साथ namespaces का उपयोग करने के लिए XML क्वेरी कैसे करें?"

दूसरे उदाहरण XML फ़ाइल में तत्व एक नेमस्पेस के लिए बाध्य हैं। आपका XPath उन तत्वों को संबोधित करने का प्रयास कर रहा है जो डिफ़ॉल्ट "नो नेमस्पेस" नाम स्थान तक सीमित हैं, इसलिए वे मेल नहीं खाते।

नाम-स्थान-उपसर्ग के साथ नाम स्थान को पंजीकृत करने के लिए सबसे पसंदीदा तरीका है। यह आपके XPath को विकसित करने, पढ़ने और बनाए रखने के लिए बहुत आसान बनाता है

हालांकि, यह अनिवार्य नहीं है कि आप नाम स्थान पर रजिस्टर करें और अपने XPath में नामस्थान-उपसर्ग का उपयोग करें।

आप एक XPath अभिव्यक्ति तैयार कर सकते हैं जो एक तत्व के लिए एक सामान्य मैच का उपयोग करता है और एक निस्संदेह फ़िल्टर जो वांछित local-name() और namespace-uri() लिए मैच को प्रतिबंधित करता है। उदाहरण के लिए:

 /*[local-name()='workbook' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'] /*[local-name()='sheets' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'] /*[local-name()='sheet' and namespace-uri()='http://schemas.openxmlformats.org/spreadsheetml/2006/main'][1] 

जैसा कि आप देख सकते हैं, यह एक बहुत ही लंबी और वर्बोजी XPath स्टेटमेंट का उत्पादन करता है जो पढ़ने (और बनाए रखने) के लिए बहुत मुश्किल है।

आप तत्व के local-name() पर भी मेल कर सकते हैं और नामस्थान को अनदेखा कर सकते हैं। उदाहरण के लिए:

 /*[local-name()='workbook']/*[local-name()='sheets']/*[local-name()='sheet'][1] 

हालांकि, आप गलत तत्वों के मिलान के जोखिम को चलाते हैं। यदि आपके एक्सएमएल में शब्दसंग्रह मिला है (जो इस उदाहरण के लिए कोई मुद्दा नहीं है) जो समान local-name() उपयोग करता है, तो आपका XPath गलत तत्वों से मिलान कर सकता है और गलत सामग्री का चयन कर सकता है:

आपकी समस्या डिफ़ॉल्ट नेमस्पेस है अपने XPath में नामस्थान के साथ कैसे निपटें यह लेख देखें: http://www.edankert.com/defaultnamespaces.html

निष्कर्ष निकालने में से एक यह है:

इसलिए, एक्सपीएल एक्सप्रेशन पर एक्सपैथ एक्सप्रेशन पर एक (डिफ़ॉल्ट) नेमस्पेस में परिभाषित करने में सक्षम होने के लिए, हमें एक नेमस्पेस प्रीफ़िक्स मैपिंग निर्दिष्ट करना होगा

ध्यान दें कि इसका मतलब यह नहीं है कि आपको अपने स्रोत दस्तावेज़ को किसी भी तरह से बदलना होगा (हालांकि यदि आप चाहें तो नामस्थान उपसर्गों को वहां रखकर मुक्त हैं)। अजीब लगता है, है ना? आप क्या करेंगे , अपने जावा कोड में एक नेमस्पेस उपसर्ग मानचित्रण बना सकते हैं और अपने XPath अभिव्यक्ति में उपसर्ग का उपयोग करें। यहां, हम spreadsheet से आपकी डिफ़ॉल्ट नेमस्पेस पर मैपिंग बनाएंगे।

 XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); // there's no default implementation for NamespaceContext...seems kind of silly, no? xpath.setNamespaceContext(new NamespaceContext() { public String getNamespaceURI(String prefix) { if (prefix == null) throw new NullPointerException("Null prefix"); else if ("spreadsheet".equals(prefix)) return "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; else if ("xml".equals(prefix)) return XMLConstants.XML_NS_URI; return XMLConstants.NULL_NS_URI; } // This method isn't necessary for XPath processing. public String getPrefix(String uri) { throw new UnsupportedOperationException(); } // This method isn't necessary for XPath processing either. public Iterator getPrefixes(String uri) { throw new UnsupportedOperationException(); } }); // note that all the elements in the expression are prefixed with our namespace mapping! XPathExpression expr = xpath.compile("/spreadsheet:workbook/spreadsheet:sheets/spreadsheet:sheet[1]"); // assuming you've got your XML document in a variable named doc... Node result = (Node) expr.evaluate(doc, XPathConstants.NODE); 

और वॉयला … अब आपको अपने तत्व को result चर में सहेजा गया है।

चेतावनी: यदि आप अपने XML को मानक JAXP कक्षाओं के साथ एक DOM के रूप में पार्स कर रहे हैं, तो अपने DocumentBuilderFactory पर setNamespaceAware(true) को कॉल करना सुनिश्चित करें अन्यथा, यह कोड काम नहीं करेगा!

स्रोत नामों में से चुनने वाले सभी नामस्थान होस्ट भाषा में एक उपसर्ग के साथ संबद्ध होना चाहिए। जावा / जेएएनएसपी में यह javax.xml.namespace.NamespaceContext का उपयोग करके प्रत्येक नाम स्थान उपसर्ग के लिए यूआरआई निर्दिष्ट करके किया जाता है। दुर्भाग्य से, एसडीके में दिए गए NamespaceContext का कोई क्रियान्वयन नहीं है

सौभाग्य से, अपना खुद लिखना बहुत आसान है:

 import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.namespace.NamespaceContext; public class SimpleNamespaceContext implements NamespaceContext { private final Map<String, String> PREF_MAP = new HashMap<String, String>(); public SimpleNamespaceContext(final Map<String, String> prefMap) { PREF_MAP.putAll(prefMap); } public String getNamespaceURI(String prefix) { return PREF_MAP.get(prefix); } public String getPrefix(String uri) { throw new UnsupportedOperationException(); } public Iterator getPrefixes(String uri) { throw new UnsupportedOperationException(); } } 

इसे इस तरह प्रयोग करें:

 XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); HashMap<String, String> prefMap = new HashMap<String, String>() {{ put("main", "http://schemas.openxmlformats.org/spreadsheetml/2006/main"); put("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships"); }}; SimpleNamespaceContext namespaces = new SimpleNamespaceContext(prefMap); xpath.setNamespaceContext(namespaces); XPathExpression expr = xpath .compile("/main:workbook/main:sheets/main:sheet[1]"); Object result = expr.evaluate(doc, XPathConstants.NODESET); 

ध्यान दें कि भले ही पहला नाम स्थान स्रोत दस्तावेज़ में एक उपसर्ग निर्दिष्ट नहीं करता (अर्थात यह डिफ़ॉल्ट नेमस्पेस है ), आप इसे किसी भी उपसर्ग के साथ किसी भी रूप से संबद्ध करना चाहिए । आपकी अभिव्यक्ति को उस उपनाम का उपयोग करके उस नेमस्पेस में नोड्स को संदर्भित करना चाहिए, जैसे आपने:

 /main:workbook/main:sheets/main:sheet[1] 

उपनाम नाम जो आप प्रत्येक नाम स्थान के साथ संबद्ध करने के लिए चुनते हैं मनमाना हैं; स्रोत एक्सएमएल में जो दिखाई देता है उन्हें मैच करने की आवश्यकता नहीं है। यह मैपिंग एक्सपीथ इंजन को यह बता देने का एक तरीका है कि एक्सप्रेशन में कोई दिए गए उपसर्ग नाम स्रोत दस्तावेज़ में विशिष्ट नामस्थान के साथ संबद्ध होता है

सुनिश्चित करें कि आप अपने एक्सएसएलटी में नाम स्थान को संदर्भित कर रहे हैं

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" > 

मैंने एक साधारण NamespaceContext कार्यान्वयन ( यहां ) लिखा है, जो इनपुट के रूप में Map<String, String> लेता है, जहां key एक उपसर्ग है, और value एक नेमस्पेस है।

यह नामस्थान कॉन्टैक्ट स्पेशिफिकेशन का अनुसरण करता है, और आप देख सकते हैं कि यह इकाई परीक्षणों में कैसे काम करता है।

 Map<String, String> mappings = new HashMap<>(); mappings.put("foo", "http://foo"); mappings.put("foo2", "http://foo"); mappings.put("bar", "http://bar"); context = new SimpleNamespaceContext(mappings); context.getNamespaceURI("foo"); // "http://foo" context.getPrefix("http://foo"); // "foo" or "foo2" context.getPrefixes("http://foo"); // ["foo", "foo2"] 

ध्यान दें कि इसका Google Guava पर निर्भरता है