Daniel Veillard wrote:
> On Tue, Mar 04, 2008 at 06:56:01PM +0000, Dan Stromberg wrote:
>   
>> I'm having a little trouble with some basic XPath queries from shell.
>>
>> I dug up a small handful of what-seem-like simple examples from http://
>> www.w3schools.com/xpath/xpath_syntax.asp and fed them into three xpath 
>> programs (one in C, one in python, one in perl), and got pretty different 
>> results from the 3, a number of which I believe must be incorrect.
>>
>> I've summarized what I found at:
>>
>> http://stromberg.dnsalias.org/~dstromberg/xml/xpath-issues.html
>>
>> Is it perhaps the case that some XPath processing programs don't do 
>> complete xpath?  Are there different levels of xpath implementation 
>> completeness?
>>     
>
> I can't debug other implementations.
I don't expect you to.
>  If you have a doubt about libxml2
> XPath implementation provide a reproductible test case, with the XML
> and how to reproduce the problem with xmllint, textXPath (in the 
> distribution), xsltproc or a standalone code demonstrating the problem.
>   
Here's the python script I was talking about.  I know next to nothing 
about the API in question; it's derived from Liam's C program:

#!/usr/bin/env python

# Written by Dan Stromberg <[EMAIL PROTECTED]>, 2008-02-28, based on
# a C program obtained from [EMAIL PROTECTED] by [EMAIL PROTECTED]
# on 2008-02-26.  Originally named parse.c, DRS renamed it to xpath

import sys
import libxml2

def main():
    commandname = sys.argv[0];

    if not sys.argv[2:]:
        sys.stderr.write("usage: %s filename xpath-expr1 xpath-expr2 ... 
xpath-exprn\n" % commandname)
        sys.exit(1)

    filename = sys.argv[1]

    myTree = libxml2.parseFile(filename)

    if not myTree:
        sys.stderr.write("%s: %s: the parse failed. Alas, I must leave 
you.\n" % \
            (commandname, filename))
        sys.exit(1)

    for arg in sys.argv[2:]:
        # now extract the given xpath expression
        result = matchXPathExpression(filename, myTree, arg)

        if not result:
            sys.stderr.write("%s: %s: no match for %s\n" % (commandname, 
filename, arg))
            sys.exit(1)

    sys.exit(0)

def matchXPathExpression(filename, doc, expression):
    context = doc.xpathNewContext()

    if not context:
        return None

    result = context.xpathEval(expression)
    if not result:
        return None

    for r in result:
        print r.getContent()

    return result

main()



> There are way you ask the tree to be built which can led to different 
> results. In that case there is no subtleties, no DTD and libxml2 seems
> to just work:
>
> paphio:~/XML -> xmllint --shell tst.xml
> / > xpath bookstore
> Object is a Node Set :
> Set contains 1 nodes:
> 1  ELEMENT bookstore
> / > xpath /bookstore
> Object is a Node Set :
> Set contains 1 nodes:
> 1  ELEMENT bookstore
> / > xpath bookstore/book
> Object is a Node Set :
> Set contains 2 nodes:
> 1  ELEMENT book
> 2  ELEMENT book
> / > xpath //book
> Object is a Node Set :
> Set contains 2 nodes:
> 1  ELEMENT book
> 2  ELEMENT book
> / > xpath //@lang
> Object is a Node Set :
> Set contains 2 nodes:
> 1  ATTRIBUTE lang
>     TEXT
>       content=eng
> 2  ATTRIBUTE lang
>     TEXT
>       content=eng
> / > 
>   
You don't seem to be using any functions in your examples.  Is there a 
reason for that?
> One thing is sure, if libxml2 XPath implementation was not accurate 
> for any of the very basic tests you pointed out in that page, well
> libxslt/xsltproc which use XPath extensively would be completely 
> unusable in practice.
>   
I don't mean to rule out that I'm misunderstanding how to use libxml2.  
Like I said, I'm a noob with it.
> Your web page report seems seriously unaccurate just for the fact
> that XPath returns programming objects (XPath objects which can be
> of various types, all node sets in those queries) and you seems to
> just look at *rendering* of those object, plus the embbeding in a
> web page, sorry that's not usable for distinguishing what may be
> right or wrong. In any case I can't comment or even analyze other
> people code.
>
>   
Here it is again as text:

bookstore - Selects all the child nodes of the bookstore element
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
/data/buildroot/cruise/checkout/3.1.3-dev/xpath: bookstore.xml: no match 
for bookstore
\/
/data/swbuild/da_build/xpath/xpath:

\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<bookstore>

        <book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>

        <book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>

</bookstore>
\/
/bookstore - Selects the root element bookstore
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:



                Harry Potter
                29.99



                Learning XML
                39.95



\/
/data/swbuild/da_build/xpath/xpath:



                Harry Potter
                29.99



                Learning XML
                39.95



\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<bookstore>

        <book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>

        <book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>

</bookstore>
\/
bookstore/book - Selects all book elements that are children of bookstore
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
/data/buildroot/cruise/checkout/3.1.3-dev/xpath: bookstore.xml: no match 
for bookstore/book
\/
/data/swbuild/da_build/xpath/xpath:

\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
<book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>-- NODE --
<book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>
\/
//book - Selects all book elements no matter where they are in the document
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:

                Harry Potter
                29.99


                Learning XML
                39.95

\/
/data/swbuild/da_build/xpath/xpath:

                Harry Potter
                29.99

\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
<book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>-- NODE --
<book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>
\/
bookstore//book - Selects all book elements that are descendant of the 
bookstore element, no matter where they are under the bookstore element
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
/data/buildroot/cruise/checkout/3.1.3-dev/xpath: bookstore.xml: no match 
for bookstore//book
\/
/data/swbuild/da_build/xpath/xpath:

\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
<book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>-- NODE --
<book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>
\/
//@lang - Selects all attributes that are named lang
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
eng
eng
\/
/data/swbuild/da_build/xpath/xpath:
eng
\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
 lang="eng"-- NODE --
 lang="eng"
\/
/bookstore/book[1] - Selects the first book element that is the child of 
the bookstore element.
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:

                Harry Potter
                29.99

\/
/data/swbuild/da_build/xpath/xpath:

                Harry Potter
                29.99

\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>
\/
/bookstore/book[last()] - Selects the last book element that is the 
child of the bookstore element
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:

                Learning XML
                39.95

\/
/data/swbuild/da_build/xpath/xpath:

                Learning XML
                39.95

\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>
\/
/bookstore/book[last()-1] - Selects the last but one book element that 
is the child of the bookstore element
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:

                Harry Potter
                29.99

\/
/data/swbuild/da_build/xpath/xpath:

                Harry Potter
                29.99

\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>
\/
/bookstore/book[position()<3] - Selects the first two book elements that 
are children of the bookstore element
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:

                Harry Potter
                29.99


                Learning XML
                39.95

\/
/data/swbuild/da_build/xpath/xpath:

                Harry Potter
                29.99

\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
<book>
                <title lang="eng">Harry Potter</title>
                <price>29.99</price>
        </book>-- NODE --
<book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>
\/
//[EMAIL PROTECTED] - Selects all the title elements that have an attribute 
named lang
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
Harry Potter
Learning XML
\/
/data/swbuild/da_build/xpath/xpath:
Harry Potter
\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
<title lang="eng">Harry Potter</title>-- NODE --
<title lang="eng">Learning XML</title>
\/
//[EMAIL PROTECTED]'eng'] - Selects all the title elements that have an 
attribute named lang with a value of 'eng'
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
Harry Potter
Learning XML
\/
/data/swbuild/da_build/xpath/xpath:
Harry Potter
\/
/usr/bin/xpath:
Found 2 nodes:
-- NODE --
<title lang="eng">Harry Potter</title>-- NODE --
<title lang="eng">Learning XML</title>
\/
/bookstore/book[price>35.00] - Selects all the book elements of the 
bookstore element that have a price element with a value greater than 35.00
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:

                Learning XML
                39.95

\/
/data/swbuild/da_build/xpath/xpath:

                Learning XML
                39.95

\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<book>
                <title lang="eng">Learning XML</title>
                <price>39.95</price>
        </book>
\/
/bookstore/book[price>35.00]/title - Selects all the title elements of 
the book elements of the bookstore element that have a price element 
with a value greater than 35.00
/data/buildroot/cruise/checkout/3.1.3-dev/xpath:
Learning XML
\/
/data/swbuild/da_build/xpath/xpath:
Learning XML
\/
/usr/bin/xpath:
Found 1 nodes:
-- NODE --
<title lang="eng">Learning XML</title>
\/


_______________________________________________
xslt mailing list, project page http://xmlsoft.org/XSLT/
[email protected]
http://mail.gnome.org/mailman/listinfo/xslt

Reply via email to