سؤال

ما هي القصة وراء XPath و دعم مساحات?هل XPath كما مواصفات تسبق مساحات?إذا كان لدي وثيقة فيها عناصر قد أعطيت مساحة الاسم الافتراضية:

<foo xmlns="uri" />

ويبدو كما لو أن بعض من XPath المعالج المكتبات لن تعترف //foo بسبب مساحة في حين أن الآخرين سوف.الخيار فريقي قد فكرت في إضافة بادئة مساحة اسم باستخدام التعبيرات العادية إلى XPath (يمكنك إضافة بادئة مساحة اسم عبر XmlNameTable) ولكن هذا يبدو هش منذ XPath هي مثل مرونة عندما يتعلق الأمر عقدة الاختبارات.

هل هناك معيار ينطبق على هذا ؟

توجهي قليلا hackish ولكن يبدو أن تعمل بشكل جيد ؛ إزالة xmlns الإعلان مع بحث/استبدال ثم تطبيق XPath.

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

هو أن نهجا عادلا أو أي شخص لديه حل هذه بشكل مختلف ؟

هل كانت مفيدة؟

المحلول

حاولت شيئا من هذا القبيل إلى ما palehorse المقترحة لا يمكن أن تحصل على عمل.منذ أن كنت الحصول على البيانات من نشر الخدمة لم أستطع تغيير xml.انتهى بي الأمر باستخدام XmlDocument و يتجاوز مثل ذلك:

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

نصائح أخرى

تحتاج المحلية-اسم():

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

على سرير من http://jcooney.net/archive/2005/08/09/6517.aspx:

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

هذا التعبير يطابق "بار" العنصر:

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

هذا واحد لن:

 //bar

القضية هي أن عنصر دون مساحة أعلن أن تكون في باطل مساحة - ولذلك إذا //foo يقابل ضد namespace كنت تنظر إلى أن 'الافتراضي' لن يكون هناك أي طريقة أن أشير إلى عنصر في مساحة فارغة.

تذكر كذلك أن بادئة مساحة اسم هو إلا اختزال الاتفاقية الحقيقي اسم العنصر (اسم مؤهل أو QName قصيرة) يتكون من كامل مساحة الاسم المحلي.تغيير بادئة مساحة اسم لا تغيير "الهوية" من عنصر - إذا كان في نفس الاسم و نفس الاسم المحلي ثم هو نفسه نوع من عنصر حتى لو البادئة مختلفة.

XPath 2.0 (أو بالأحرى XSLT 2.0) له مفهوم 'الافتراضي xpath مساحة'.يمكنك تعيين xpath-الافتراضي-مساحة السمة على xsl:الأنماط عنصر.

إذا كنت تحاول استخدام xslt يمكنك إضافة مساحة إلى إعلان الأنماط.إذا كنت تفعل ذلك ، يجب التأكد من أن هناك بادئة أو أنها لن تعمل.إذا كان مصدر XML لا البادئة, التي لا تزال بخير ، يمكنك إضافة الخاصة بك البادئة في الأنماط.

الأنماط

<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>

أو شيء من هذا القبيل.

باستخدام 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);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top