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