XPath ट्रिक
आपका उदाहरण थोड़ा मुश्किल था (पहले)। लेकिन इस XPath क्वेरी, जबकि बहुत लंबे समय तक, काम करना चाहिए:
//spring/*[local-name() = 'objects' and namespace-uri() = 'http://www.springframework.net']/*[@id='CultureResolver' and local-name() = 'object' and namespace-uri() = 'http://www.springframework.net']/@type
मैं करने के लिए this answer में इस चाल की खोज की एसओ c# - Declare namespaces within XPath expression सवाल है, लेकिन मैं वास्तव में यह पता चला के बाद मैं पहले से ही इस सवाल का जवाब (मूल) तैनात था।
मैंने नीचे अपना अधिकांश मूल उत्तर छोड़ा है और मैंने अपने मूल उत्तर को गलत तरीके से कैसे जोड़ा है इसके बारे में अतिरिक्त अनुभाग भी जोड़े हैं।
मेरे उदाहरण
मैं NLog लिए यह करना चाहते थे;
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true">
...
<targets>
<target name="HipChat" xsi:type="MethodCall" className="DbNecromancer.Logging, DbNecromancer" methodName="SendHipChatRoomNotification">
<parameter layout="1234567" name="roomId" />
<parameter layout="blah-blah-blah" name="authToken" />
<parameter layout="${message-layout}" name="message" />
<parameter layout="${level}" name="nLogLevel" />
</target>
</targets>
...
</nlog>
यहाँ मेरी Parameters.xml फ़ाइल से प्रासंगिक XPath क्वेरी के लिए "roomId" का एक मूल्य के साथ parameter
तत्व की layout
विशेषता बदल सकते हैं: यहाँ मेरी NLog.config फ़ाइल का एक उदाहरण है name
विशेषता:
/nlog/targets/target[@name='HipChat']/parameter[@name='roomId']/@layout
आप पुष्टि कर सकते हैं कि इसके बाद के संस्करण XPath वांछित विशेषता this free online XPath tester का उपयोग कर मैच के लिए विफल रहता है। आप यह भी पुष्टि कर सकते हैं कि यह वेब परिनियोजन का उपयोग करके विफल रहता है!
लेकिन मैं दोनों ऑनलाइन परीक्षक में और वेब तैनात के माध्यम से, काम करने के लिए इस प्राप्त करने में सक्षम था, वाइल्डकार्ड का उपयोग या में नाम स्थान घोषणा को हटाने NLog.config बिना। चाल एक नामस्थान उपसर्ग जोड़ने के लिए था।
यहां एनएलओजी में संशोधित लाइनें हैं।config:
<nlog:nlog xmlns:nlog="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" throwExceptions="true">
...
</nlog:nlog>
यहाँ संशोधित XPath क्वेरी है:
/nlog:nlog/targets/target[@name='HipChat']/parameter[@name='roomId']/@layout
आपका उदाहरण
मैं अपने उदाहरण बस जहाँ आपके उदाहरण एक उपसर्ग जोड़कर ऑनलाइन परीक्षक में काम करने के लिए नहीं मिल सका एक नामस्थान का उपयोग कर रहा है (और मेरे पास एक परियोजना नहीं है जो वसंत का उपयोग करती है)। परीक्षक के उत्पादन में जब मैं सिर्फ एक उपसर्ग जोड़ने का प्रयास:
त्रुटि - XPath अभिव्यक्ति का मूल्यांकन करने में विफल: उपसर्ग एक नाम स्थान को हल करना चाहिए: वसंत
हालांकि, मैं इसे पाने के लिए कर रहा था निम्नलिखित करने के द्वारा काम करने के लिए (जो मुझे लगता है कि 'सही' हो सकता है)।
यहाँ अपने XML में लाइनों मैं बदल गया है:
/spring/spring:objects/object[@id='CultureResolver']/@type
क्यों 'मेरा उदाहरण' और 'आपका उदाहरण' कर रहे हैं (सूक्ष्मता) गलत
:
<spring xmlns="" xmlns:spring="http://www.springframework.net">
<spring:objects>
...
</spring:objects>
यहाँ संशोधित XPath क्वेरी है
समस्या, जैसा कि मुझे लगता है (मुश्किल से) इसे समझते हैं, यह है कि एक उपसर्ग के बिना नामस्थान घोषित करना उपसर्ग के साथ एक घोषित करने से बहुत अलग है।
उपसर्ग के साथ एक नामस्थान घोषित करना बस नामस्थान और इसके उपसर्ग, घोषित करता है लेकिन यह किसी भी तत्व का नामस्थान नहीं बदलता है।
उपसर्ग के बिना नामस्थान घोषित करना उस तत्व को परिभाषित करता है जिसमें तत्व परिभाषित किया गया है और उस तत्व के सभी बाल तत्वों के लिए।
तो, आपके उदाहरण के लिए, आप निम्न पंक्ति आपके XML में संशोधित कर और अपने मूल XPath क्वेरी काम करेगा:
<objects xmlns:spring="http://www.springframework.net">
[बस नाम स्थान के लिए spring
उपसर्ग जोड़ें।]
है कि क्योंकि (या मेरी कामकाजी परिकल्पना के अनुसार है) objects
तत्व (और उसके सभी बच्चों) को उपसर्ग जोड़ने के बिना नामस्थान घोषणा में उपसर्ग जोड़ना एक्सएमएल को संशोधित करना 'महत्वपूर्ण' है क्योंकि यह उन तत्वों को नामस्थान से हटा रहा है ।
सही ढंग से एक्सएमएल के शब्दों को संशोधित किए बिना एक उपसर्ग जोड़ने के लिए, अपने XML के रूप में किया जाना चाहिए इस प्रकार है:
<spring>
<spring:objects xmlns:spring="http://www.springframework.net">
<spring:object id="CultureResolver" type="Spring.Globalization.Resolvers.SessionCultureResolver, Spring.Web">
<!--configure for server-->
<spring:property name="DefaultCulture" value="en" />
</spring:object>
</spring:objects>
</spring>
और अपने XPath क्वेरी इस तरह होना चाहिए:
//spring/spring:objects/spring:object[@id='CultureResolver']/@type
केवल समस्या है कि यह (the online tester में, और शायद MSDeploy के साथ नहीं) काम नहीं करता है।
उपर्युक्त काम नहीं करता है क्योंकि XPath इंजनों को नेमस्पेस पंजीकृत होने की आवश्यकता होती है (XML दस्तावेज़ में घोषित नामस्थानों से अलग)। लेकिन, जैसा कि वेब परिनियोजन और ऑनलाइन परीक्षक दोनों ऐसा करते हैं, XML दस्तावेज़ के मूल तत्व में कोई भी घोषणा स्वचालित रूप से पंजीकृत होती है। और यह बहुत उपयोगी है क्योंकि वेब नियोजन पैरामीटर परिवर्तन का उपयोग करते समय मुझे नेमस्पेस पंजीकृत करने के किसी भी तरीके से नहीं पता है।
अधिक गहराई से स्पष्टीकरण के लिए मेरे संबंधित प्रश्न Do XML namespaces need to be declared in the root element to be matchable by an XPath query? के उत्तर देखें।
आपका (सही) उदाहरण
एक्सएमएल:
<spring xmlns:spring="http://www.springframework.net">
<spring:objects>
<spring:object id="CultureResolver" type="Spring.Globalization.Resolvers.SessionCultureResolver, Spring.Web">
<!--configure for server-->
<spring:property name="DefaultCulture" value="en" />
</spring:object>
</spring:objects>
</spring>
XPath क्वेरी:
//spring/spring:objects/spring:object[@id='CultureResolver']/@type
निष्कर्ष
आप लंबे समय XPath प्रश्नों कोई आपत्ति नहीं है, चाल का उपयोग शीर्ष पर। अन्यथा, अपने एक्सएमएल नेमस्पेस घोषणाओं को संशोधित करें ताकि वे एक उपसर्ग शामिल कर सकें और वे आपके XML दस्तावेज़ के मूल तत्व में स्थित हैं।
ग्रेट धन्यवाद, मेरे लिए भी काम करता है! जो लोग गुगल रहे हैं उनके लिए: तैनाती पैरामीटर.एक्सएमएल और एमवीसी साइटमैप के साथ एक ही समस्या थी। MvcSiteMap नोड में xmlns की वजह से IIS आयात इस तरह xpath से मिलान करने में सक्षम नहीं था: "/ mvcSiteMap/mvcSiteMapNode/mvcSiteMapNode [@ title = 'मेरा शीर्षक']/@ url"। – Kirill
आपका कामकाज निश्चित रूप से काम करता है, और जब मैंने पहली बार आपका जवाब पाया, तो मैंने आपको ऊपर उठाया, लेकिन मुझे हाल ही में पता चला कि आप गलत हैं कि XPath क्वेरी लिखना असंभव है जो एक्सएमएल नेमस्पेस को सही तरीके से निर्दिष्ट करता है, और ऐसा करने के लिए वेब समर्थन तैनात करें। –