2009-12-31 17 views
5

मैं XML फ़ाइल में दिखाई देने वाले सभी तत्वों के नामों की सूची प्राप्त करने के लिए XPath का उपयोग करना चाहता हूं। हालांकि, मैं नहीं चाहता कि कोई नाम दोहराया जाए, इसलिए पिछले तत्व के समान नाम वाला तत्व मिलान नहीं किया जाना चाहिए। अब तक, मुझे मिल गया है:XPath अद्वितीय तत्व नाम प्राप्त करने के लिए

*[not(local-name() = local-name(preceding::*))] 

यह ठीक से निष्पादित करता है लेकिन यह डुप्लीकेट को थका देता है। यह डुप्लिकेट क्यों थूकता है और मैं उन्हें कैसे खत्म कर सकता हूं? (मैं फ़ायरफ़ॉक्स के XPath इंजन का उपयोग कर रहा हूं।)

+0

आपका कोड spits डुप्लिकेट आउट करें, क्योंकि सूची का आदेश नहीं दिया गया है। यह एक आदेशित सूची पर काम करेगा। –

उत्तर

5

आपको डुप्लिकेट मिल रहे हैं क्योंकि आपका फ़िल्टर उस तरीके का मूल्यांकन नहीं कर रहा है जिस तरह से आप सोचते हैं।

स्थानीय नाम() समारोह प्रथम नोड nodeset में स्थानीय नाम देता है।

आपका अनुमानित फ़िल्टर काम करने का एकमात्र समय यह है कि यदि तत्व पहले के तत्व के समान नाम था।

मुझे नहीं लगता कि आप शुद्ध XPATH 1.0 आत्मा के साथ जो चाहते हैं उसे पूरा करने में सक्षम होंगे। आप इसे XPATH 2.0 में कर सकते हैं, लेकिन यह फ़ायरफ़ॉक्स के साथ काम नहीं करेगा।

XSLT में आप आप क्या चाहते हैं पूरा करने के लिए meunchien method उपयोग कर सकते हैं।

नीचे एक उदाहरण है। आप किसी भी नमूना XML प्रदान नहीं किया है, इसलिए मैं रखा यह बहुत सामान्य (जैसे // * दस्तावेज़ में सभी तत्वों के लिए मेल खाता है):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="xml"/> 
<xsl:key name="names" match="//*" use="local-name(.)"/> 
<xsl:template match="/"> 
    <xsl:for-each select="//*[generate-id(.) = generate-id(key('names', local-name(.)))]"> 
     <!--Do something with the unique list of elements--> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
+0

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

1

मैं पहले सभी तत्वों की एक सूची प्राप्त करने की सिफारिश करता हूं और फिर सूची के माध्यम से पुन: प्रयास करता हूं और डुप्लिकेट का पता लगाने के लिए उन्हें एक शब्दकोश में जोड़ता हूं।

उदाहरण के लिए, छद्म कोड में:

var allElements = doc.select("//node()"); 
var distinctElementTypes = new object(); 
foreach (var elem in allElements) { 
    distinctElementTypes[elem.name] = elem.name; 
} 

और अब distinctElementTypes अलग तत्व नामों की एक शब्दकोश हो जाएगा।

+0

उत्तर के लिए धन्यवाद। मैं इस दृष्टिकोण को ले सकता हूं लेकिन xpath केवल कोड की एक पंक्ति की आवश्यकता है। साथ ही, यह वास्तव में समस्या का प्रकार xpath के लिए डिज़ाइन किया गया है। मैं जानना चाहता हूं कि दिए गए उदाहरण में क्या गलत है, क्योंकि मैं अपनी एक्सपैथ शिक्षा आगे बढ़ाना चाहता हूं। जहां तक ​​मैं कह सकता हूं, इसे काम करना चाहिए, लेकिन ऐसा नहीं है। – mawrya

+0

मुझे यकीन नहीं है कि 'पिछला' क्यों काम नहीं कर रहा है। क्या यह हो सकता है कि यह केवल * सभी * पूर्ववर्ती नोड्स के विपरीत प्रश्न में नोड के पिछले भाई नोड्स की तुलना में तुलना करता है? – Eilon

+0

यह पिछले-भाई :: अक्ष होगा। डब्ल्यू 3 सी कहता है: पूर्व अक्ष में उसी दस्तावेज़ में सभी नोड्स होते हैं जो संदर्भ नोड के रूप में दस्तावेज़ ऑर्डर में संदर्भ नोड से पहले होते हैं, किसी भी पूर्वजों को छोड़कर और विशेषता नोड्स और नेमस्पेस नोड को छोड़कर। तो, मैं देख सकता हूं कि यदि मुझे समान नाम वाले तत्व पूर्वजों हैं, तो मुझे डुप्लीकेट क्यों मिल सकता है, लेकिन मुझे भाई तत्वों से भी डुप्लीकेट मिल रहा है! – mawrya

6

XPath 2.0 में मान्य:

distinct-values(//*/name()) 
संबंधित मुद्दे