2008-08-14 15 views
16

XPath के पीछे की कहानी और नामस्थानों के लिए समर्थन क्या है? क्या विनिर्देश के रूप में XPath ने नेमस्पेस से पहले किया था? अगर मैं एक दस्तावेज़ जहां तत्वों एक डिफ़ॉल्ट नाम स्थान दिया गया है है:XPATHS और डिफ़ॉल्ट नामस्थान

<foo xmlns="uri" /> 

ऐसा लगता है जैसे XPath प्रोसेसर पुस्तकालयों में से कुछ हालांकि नाम स्थान की वजह से //foo पहचान नहीं होगा जबकि अन्य होगा। मेरी टीम ने जिस विकल्प के बारे में सोचा है, वह है XPath को नियमित अभिव्यक्तियों का उपयोग करके नामस्थान उपसर्ग जोड़ना (आप XmlNameTable के माध्यम से एक नामस्थान उपसर्ग जोड़ सकते हैं) लेकिन ऐसा लगता है कि नोड परीक्षणों की बात करते समय XPath ऐसी लचीली भाषा है।

क्या कोई मानक है जो इस पर लागू होता है?

मेरा दृष्टिकोण थोड़ा हैकिश है लेकिन ऐसा लगता है कि यह ठीक काम करता है; मैं xmlns एक खोज/प्रतिस्थापन के साथ घोषणा को हटा देता हूं और फिर XPath लागू करता हूं।

string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty); 

क्या यह एक उचित दृष्टिकोण है या किसी ने इसे अलग हल किया है?

उत्तर

10

मैंने कुछ ऐसा करने की कोशिश की जो कि प्रस्तावित किया गया था और इसे काम नहीं कर सका। चूंकि मुझे एक प्रकाशित सेवा से डेटा मिल रहा था, इसलिए मैं एक्सएमएल नहीं बदल सका।

XmlDocument doc = new XmlDocument(); 
doc.LoadXml(xmlWithBogusNamespace);    
XmlNamespaceManager nSpace = new XmlNamespaceManager(doc.NameTable); 
nSpace.AddNamespace("myNs", "http://theirUri"); 

XmlNodeList nodes = doc.SelectNodes("//myNs:NodesIWant",nSpace); 
//etc 
+0

यदि आप कई गहराई पर नोड्स का उपयोग करना चुनना चाहते हैं, तो आप कुछ ऐसा करने के लिए समाप्त होते हैं: 'xml.SelectNodes (" kml: kml/kml: दस्तावेज़/kml: फ़ोल्डर ", प्रबंधक)' –

15

आप स्थानीय नाम() की आवश्यकता है:

http://www.w3.org/TR/xpath#function-local-name

http://jcooney.net/archive/2005/08/09/6517.aspx से पालना करने के लिए:

//*[local-name()='bar'] 

:

<foo xmlns='urn:foo'> 
    <bar> 
    <asdf/> 
    </bar>    
</foo> 

यह अभिव्यक्ति "बार" तत्व से मेल खाएगी यह एक नहीं होगा:

//bar 
+0

यदि आपका समाधान दोनों का चयन करेगा। –

0

यदि आप xslt का उपयोग करने का प्रयास कर रहे हैं तो आप स्टाइलशीट घोषणा में नामस्थान जोड़ सकते हैं। यदि आप ऐसा करते हैं, तो आपको यह सुनिश्चित करना होगा कि उपसर्ग है या यह काम नहीं करेगा। अगर स्रोत एक्सएमएल में उपसर्ग नहीं है, तो यह अभी भी ठीक है, तो आप स्टाइलशीट में अपना खुद का उपसर्ग जोड़ते हैं।

स्टाइल शीट

<xsl:stylesheet 
    xmlns:fb="uri" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="fb:foo/bar"> 
     <!-- do stuff here --> 
    </xsl:template> 
</xsl:stylsheet> 

या ऐसा ही कुछ।

4

समस्या यह है कि नामस्थान के बिना एक तत्व नल नेमस्पेस में घोषित किया जाता है - इसलिए यदि नामस्थान के खिलाफ // foo मिलान किया गया है तो आप 'डिफ़ॉल्ट' मानते हैं, इसमें किसी तत्व को संदर्भित करने का कोई तरीका नहीं होगा शून्य नामस्थान।

याद रखें कि नामस्थान के लिए उपसर्ग केवल एक शॉर्टेंड सम्मेलन है, असली तत्व नाम (योग्य नाम, या संक्षिप्त नाम के लिए QName) में पूर्ण नामस्थान और स्थानीय नाम शामिल है। किसी नामस्थान के लिए उपसर्ग को बदलने से तत्व की 'पहचान' नहीं बदली जाती है - यदि यह समान नामस्थान और उसी स्थानीय नाम में है तो यह वही तत्व है, भले ही उपसर्ग अलग है।

XPath 2.0 (या बल्कि XSLT 2.0) में 'डिफ़ॉल्ट xpath नेमस्पेस' की अवधारणा है। आप एक्सएसएल: स्टाइलशीट तत्व पर xpath-default-namespace विशेषता सेट कर सकते हैं।

0

का उपयोग libxml ऐसा लगता है यह काम करता है:: मैं तो जैसे XmlDocument और XmlNamespaceManager का उपयोग कर समाप्त हो गया अपने दस्तावेज़ में एक अलग नाम स्थान से दूसरे `bar` है, तो

http://xmlsoft.org/examples/xpath1.c

int 
register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList) { 
    xmlChar* nsListDup; 
    xmlChar* prefix; 
    xmlChar* href; 
    xmlChar* next; 

    assert(xpathCtx); 
    assert(nsList); 

    nsListDup = xmlStrdup(nsList); 
    if(nsListDup == NULL) { 
    fprintf(stderr, "Error: unable to strdup namespaces list\n"); 
    return(-1); 
    } 

    next = nsListDup; 
    while(next != NULL) { 
    /* skip spaces */ 
    while((*next) == ' ') next++; 
    if((*next) == '\0') break; 

    /* find prefix */ 
    prefix = next; 
    next = (xmlChar*)xmlStrchr(next, '='); 
    if(next == NULL) { 
     fprintf(stderr,"Error: invalid namespaces list format\n"); 
     xmlFree(nsListDup); 
     return(-1); 
    } 
    *(next++) = '\0'; 

    /* find href */ 
    href = next; 
    next = (xmlChar*)xmlStrchr(next, ' '); 
    if(next != NULL) { 
     *(next++) = '\0'; 
    } 

    /* do register namespace */ 
    if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0) { 
     fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href); 
     xmlFree(nsListDup); 
     return(-1); 
    } 
    } 

    xmlFree(nsListDup); 
    return(0); 
} 
संबंधित मुद्दे