Re: [xml] XPath with default namespace



On Tue, Aug 07, 2001 at 08:53:55PM +0100, Stephen Lord wrote:
How can I ensure that I have the correct namespaces set up in the context
 before using xPath to query for an element that defines it's namespace
 within that element?

  Are you within an XSLT document, if yes then the namespaces in scope
are used.
  If you are within an extension function, build a list of namespaces
in scope at the current extension function, assuming the current node
is inst, then:

    int nsNr = 0;
    xmlNsPtr *nsList = xmlGetNsList(inst->doc, inst);

    if (nsList != NULL) {
        while (cur->nsList[i] != NULL)
            i++;
    }

  Then pass it to the XPath context
    xmlXPathContextPtr xpathCtxt;


    xpathCtxt->namespaces = nsList;
    xpathCtxt->nsNr = nsNr;

  Don't forget to xmlFree(nsList) once done.

If I try :
 //definitions/types/xsd:schema/*

XPath returns:
 Error xpath.c:7976: Undefined namespace prefix
 //ofwsdl:definitions/ofwsdl:types/xsd:schema/*
                                               ^
 Error xpath.c:7970: Invalid type
 //ofwsdl:definitions/ofwsdl:types/xsd:schema/*
                                               ^
 Which is obviously because the namespace is not defined yet.

  Right
  
I can hack it by predefining an alternative prefix e.g ofxsd2000 to the URI
 in question but that implies that I have to evaluate a path for each
 possible value of xsd: i.e.

         xmlXPathRegisterNs(ctx, (xmlChar *)"ofxsd2001", (xmlChar
*)"http://www.w3.org/2001/XMLSchema";);
         xmlXPathRegisterNs(ctx, (xmlChar *)"ofxsd2000", (xmlChar
*)"http://www.w3.org/2000/10/XMLSchema";);
         xmlXPathRegisterNs(ctx, (xmlChar *)"ofxsd1999", (xmlChar
*)"http://www.w3.org/1999/XMLSchema";);

  xmlXPathRegisterNs() is another, more global (and hence less reliable
considering that namespaces are not global) way of doing this. I don't
recommend it, it only makes sense for XPointers evaluation (since theu
don't inherit namespaces from their context).

and then search with all three possible mappings of xsd to the above URIs.
 Or do I have to walk the tree to the schema element and then load the
 namespaces?

  Use xmlGetNsList() to be sure.

Also, I am unable to figure out how to list out the current namespaces in a
 given context. Any help would be greatly appreciated.

  If you have a node then you can compute what is the prefix associated
to a namespace in scope or what is the namespace name associated to a given
prefix:

xmlNsPtr        xmlSearchNs             (xmlDocPtr doc,
                                         xmlNodePtr node,
                                         const xmlChar *nameSpace);
xmlNsPtr        xmlSearchNsByHref       (xmlDocPtr doc,
                                         xmlNodePtr node,
                                         const xmlChar *href);
 
  the prefix (if any) is in the xmlNsPtr returned as ns->prefix, the
namespace name is ns->href.

  Namespaces are shared within the full subtree, that's a non-direct
mapping of the XPath data model but is equivalent (different memory/cpu
tradeoff).

Daniel

-- 
Daniel Veillard      | Red Hat Network http://redhat.com/products/network/
veillard redhat com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]