[xml] QName in Node Tests



All,

I've had some unexpected results using the XPath support in libxml2. I'm unclear about what is supposed to happen even after having pored over the XPath 1.0 spec. Specifically, given a document fragment

<top>
  <xyzzy/>
  <xyzzy xmlns="http://xyzzy.org/"/>
</top>

the node test '//xyzzy' matches only the first of the xyzzy elements rather than both as I expected.

Having read section "2.3 Node Tests" of XPath 1.0 which states

A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context.

I take the statement "except that the default namespace declared with xmlns is not used" to mean that both xyzzy elements in the example above should have been matched although I am by no means clear that this is what is intended.

Looking at the code in xpath.c, function xmlXPathNodeCollectAndTest() near line 9122 there is the following code

                case NODE_TEST_NAME:
                    switch (cur->type) {
                        case XML_ELEMENT_NODE:
                            if (xmlStrEqual(name, cur->name)) {
                                if (prefix == NULL) {
                                    if (cur->ns == NULL) {
#ifdef DEBUG_STEP
                                        n++;
#endif
                                        addNode(list, cur);
                                    }
                                } else {
                                    if ((cur->ns != NULL) &&
                                        (xmlStrEqual(URI,
                                                     cur->ns->href))) {
#ifdef DEBUG_STEP
                                        n++;
#endif
                                        addNode(list, cur);
                                    }
                                }
                            }
                            break;

My interpretation of the standard implies that the test written
                                 if (prefix == NULL) {
                                    if (cur->ns == NULL) {
should read
                                 if (prefix == NULL) {
                                    if ((cur->ns == NULL)
                                        || (cur->ns->prefix == NULL)) {

as is the case for an XML_ATTRIBUTE_NODE which follows in xpath.c. The same would apply to a few other places in the code for xpath.c where a similar test is necessary. This would seem to be emphasised by the parenthetical statement from the above quoted text '(this is the same way attribute names are expanded)'.

Is this an accurate assessment of XPath behaviour?

Regards,
Brian Stafford




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