Re: [xml] xpath problem



On Thu, Aug 29, 2002 at 03:57:09AM -0400, Daniel Veillard wrote:
On Wed, Aug 28, 2002 at 10:09:01PM -0700, Aleksey Sanin wrote:


The problem:
===========================================================
There are two files a.xml and b.xml with a difference of \n in the last 
line:

yes and at the XPath data model it means the EndUsers node has one more child
which is a text node with the \n

--- a.xml ---
<?xml version="1.0"?>
<EndUsers><EndUser Id="aaa"><Version>1.0</Version>
</EndUser>
</EndUsers>
--- b. xml ---
<?xml version="1.0"?>
<EndUsers><EndUser Id="aaa"><Version>1.0</Version>
</EndUser></EndUsers>
-------------
And there is an XPath expression:
(//. | //@* | //namespace::*) [ (ancestor::node() = 
/EndUsers[1]/child::EndUser[ Id='aaa']) ]

The expected result is that this expression selects all childs of the 
EndUser node with
Id attribute equal to 'aaa' (I know that it's ugly because the Id 
attribute selected w/o node :) ).  
However, it should work! But running this expression on these two files 
gives different results
(correct result in the a.xml case and wrong result in the b.xml case):

[aleksey shell dd]$ ./testXPath --debug -f test.xpath -i a.xml
========================
Expression: (//. | //@* | //namespace::*)[(ancestor::node() = 
/EndUsers[1]/child::EndUser[ Id='aaa'])]
Object is a Node Set :
Set contains 6 nodes:
1  ATTRIBUTE Id
    TEXT
      content=aaa
2  ELEMENT Version
3  TEXT
    content=1.0
4  TEXT
    content=
5  namespace xml href=http://www.w3.org/XML/1998/namespace
6  namespace xml href=http://www.w3.org/XML/1998/namespace

[aleksey shell dd]$ ./testXPath --debug -f test.xpath -i b.xml
========================
Expression: (//. | //@* | //namespace::*)[(ancestor::node() = 
/EndUsers[1]/child::EndUser[ Id='aaa'])]
Object is a Node Set :
Set contains 8 nodes:
1  ELEMENT EndUser
    ATTRIBUTE Id
      TEXT
        content=aaa
2  ATTRIBUTE Id
    TEXT
      content=aaa
3  ELEMENT Version
4  TEXT
    content=1.0
5  TEXT
    content=
6  namespace xml href=http://www.w3.org/XML/1998/namespace
7  namespace xml href=http://www.w3.org/XML/1998/namespace
8  namespace xml href=http://www.w3.org/XML/1998/namespace

  The behaviour of '(//. | //@* | //namespace::*)' seems okay, it
selects 11 nodes on a.xml and 10 on b.xml . But the fact that 
EndUser get selected in the expression in b.xml is a bug clearly :-(

  Conclusion: it's not a bug !

  [(ancestor::node() = /EndUsers[1]/child::EndUser[ Id='aaa'])]
does a comparison between nodesets, defined at
   http://www.w3.org/TR/xpath#booleans

 "If both objects to be compared are node-sets, then the comparison
 will be true if and only if there is a node in the first node-set and
 a node in the second node-set such that the result of performing the
 comparison on the string-values of the two nodes is true."

  in the case of b.xml the string-value of EndUsers and EndUser
are the same (because there is no \n to differenciate them), so 
EndUsers matches the criteria and the EndUser child is selected in the
resutling node-list.

  The bug is in the expression given, it does *not* select all childs
of the EndUser node !
 
   NOTABUG, CLOSED

  XPath is subtle :-\

Daniel

-- 
Daniel Veillard      | Red Hat Network https://rhn.redhat.com/
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]