XPATHS और डिफ़ॉल्ट नामस्थान

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


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

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

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

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

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

0
ro fr bn

5 उत्तर

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

स्टाइल शीट



    
        <!--  do stuff here -->
    

या कुछ इस तरह का।

0
जोड़ा

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

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: फ़ोल्डर", प्रबंधक)
जोड़ा लेखक Drew Noakes, स्रोत

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

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

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


  
    
              

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

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

यह एक नहीं होगा:

 //bar
0
जोड़ा
यदि आपके दस्तावेज़ में एक अलग नामस्थान से बार है, तो आपका समाधान दोनों का चयन करेगा।
जोड़ा लेखक Micha Wiedenmann, स्रोत
सही है, लेकिन मुझे लगता है कि ओपी की तरह ही नामस्थानों को फिर से बढ़ाने से बेहतर है।
जोड़ा लेखक Stu, स्रोत

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

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

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

0
जोड़ा

Libxml का उपयोग करना ऐसा लगता है कि यह काम करता है:

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);
}
0
जोड़ा