Connecting Tech Pros Worldwide Help | Site Map

XPathNavigator.Matches doesn't work as I expect

=?Utf-8?B?a2FydXpv?=
Guest
 
Posts: n/a
#1: Sep 5 '08
Hi,
I cannot guess, why some XPath expressions in my code returns false and some
even errors, while the others returne true as I expected. I'am workin with VS
2008 Express Edition.

Dim xEl As XElement = <root><child1><child2/></child1></root>
Dim nav As XPathNavigator = xEl.CreateNavigator

nav.MoveToRoot()

Console.WriteLine(nav.Matches("*")) 'returns FALSE
Console.WriteLine(nav.Matches("root")) 'returns FALSE
Console.WriteLine(nav.Matches("/root")) 'returns FALSE

Console.WriteLine("--------------------------")

nav.MoveToFirstChild()

Console.WriteLine(nav.Matches("*")) 'OK, returns TRUE
Console.WriteLine(nav.Matches("child1")) 'OK, returns TRUE
Console.WriteLine(nav.Matches("child1[parent::root]")) 'OK, returns TRUE
Console.WriteLine(nav.Matches("//root/child1")) 'returns FALSE

Console.WriteLine(nav.Matches("*[self::child1]")) 'OK, returns TRUE
'Console.WriteLine(nav.Matches("self::child1")) 'raise error
'Console.WriteLine(nav.Matches("*/self::child1")) 'raise error

Console.ReadLine()
Pavel Minaev
Guest
 
Posts: n/a
#2: Sep 5 '08

re: XPathNavigator.Matches doesn't work as I expect



"karuzo" <karuzo@discussions.microsoft.comwrote in message
news:24F9B3F5-154D-4D74-A7C3-4CBD42230FA5@microsoft.com...
Quote:
Hi,
I cannot guess, why some XPath expressions in my code returns false and
some
even errors, while the others returne true as I expected. I'am workin with
VS
2008 Express Edition.
>
Dim xEl As XElement = <root><child1><child2/></child1></root>
Dim nav As XPathNavigator = xEl.CreateNavigator
>
nav.MoveToRoot()
>
Console.WriteLine(nav.Matches("*")) 'returns FALSE
Console.WriteLine(nav.Matches("root")) 'returns FALSE
Console.WriteLine(nav.Matches("/root")) 'returns FALSE
Your problem is that you're trying to use an XElement (and not a
full-fledged XDocument) for XPath, which screws up the XPath Document Model.

Consider: in XPath, an XML document has a root (aka document) _node_ ("/"),
and a root _element_ ("/*"). When you do MoveToRoot on XPathNavigator, you
navigate to the document node, and you'll need to MoveToFirstChild to
position it on the root element. When you deal with an XmlDocument or
XDocument, the document itself is that nameless root document node. However,
when you deal with an XML fragment, there's no document, so the topmost
node - that is, your "root" - becomes the document node for XDM purposes;
except that it doesn't really qualify as such, because the document node is
not supposed to be an element - it has its own distinct type. This seems to
confuse XPath provider here, so "root" ends up matching neither an element
(probably because an element should always have a parent node), nor "/"
(probably because "/" is not supposed to be an element node).

If you rewrite your example and make xEl an XDocument, you'll see that it
works as expected (though you'll need to MoveToFirstChild immediately after
MoveToRoot).


Anthony Jones
Guest
 
Posts: n/a
#3: Sep 5 '08

re: XPathNavigator.Matches doesn't work as I expect


"Pavel Minaev" <int19h@gmail.comwrote in message
news:O$s24o1DJHA.3904@TK2MSFTNGP02.phx.gbl...
Quote:
>
"karuzo" <karuzo@discussions.microsoft.comwrote in message
news:24F9B3F5-154D-4D74-A7C3-4CBD42230FA5@microsoft.com...
Quote:
>Hi,
>I cannot guess, why some XPath expressions in my code returns false and
>some
>even errors, while the others returne true as I expected. I'am workin
>with VS
>2008 Express Edition.
>>
>Dim xEl As XElement = <root><child1><child2/></child1></root>
>Dim nav As XPathNavigator = xEl.CreateNavigator
>>
>nav.MoveToRoot()
>>
>Console.WriteLine(nav.Matches("*")) 'returns FALSE
>Console.WriteLine(nav.Matches("root")) 'returns FALSE
>Console.WriteLine(nav.Matches("/root")) 'returns FALSE
>
Your problem is that you're trying to use an XElement (and not a
full-fledged XDocument) for XPath, which screws up the XPath Document
Model.
>
Consider: in XPath, an XML document has a root (aka document) _node_
("/"), and a root _element_ ("/*"). When you do MoveToRoot on
XPathNavigator, you navigate to the document node, and you'll need to
MoveToFirstChild to position it on the root element. When you deal with an
XmlDocument or XDocument, the document itself is that nameless root
document node. However, when you deal with an XML fragment, there's no
document, so the topmost node - that is, your "root" - becomes the
document node for XDM purposes; except that it doesn't really qualify as
such, because the document node is not supposed to be an element - it has
its own distinct type. This seems to confuse XPath provider here, so
"root" ends up matching neither an element (probably because an element
should always have a parent node), nor "/" (probably because "/" is not
supposed to be an element node).
>
If you rewrite your example and make xEl an XDocument, you'll see that it
works as expected (though you'll need to MoveToFirstChild immediately
after MoveToRoot).
>
If this is true its very unsatisfactory. XPath does not define that the
root node should be the Document. Indeed in many cases its important that
it isn't. E.g applying XSL to a child node in a document should have that
child node treated as the root as far as any XPath present in the XSL is
concerned.

--
Anthony Jones - MVP ASP/ASP.NET

=?Utf-8?B?a2FydXpv?=
Guest
 
Posts: n/a
#4: Sep 5 '08

re: XPathNavigator.Matches doesn't work as I expect


Thank you, Pavel,
it solves my problem. I still don't understand the errors in the last two
(commented) line of code but I doesn't matter much.
Regards, Martin

"Pavel Minaev" wrote:
Quote:
>
"karuzo" <karuzo@discussions.microsoft.comwrote in message
news:24F9B3F5-154D-4D74-A7C3-4CBD42230FA5@microsoft.com...
Quote:
Hi,
I cannot guess, why some XPath expressions in my code returns false and
some
even errors, while the others returne true as I expected. I'am workin with
VS
2008 Express Edition.

Dim xEl As XElement = <root><child1><child2/></child1></root>
Dim nav As XPathNavigator = xEl.CreateNavigator

nav.MoveToRoot()

Console.WriteLine(nav.Matches("*")) 'returns FALSE
Console.WriteLine(nav.Matches("root")) 'returns FALSE
Console.WriteLine(nav.Matches("/root")) 'returns FALSE
>
Your problem is that you're trying to use an XElement (and not a
full-fledged XDocument) for XPath, which screws up the XPath Document Model.
>
Consider: in XPath, an XML document has a root (aka document) _node_ ("/"),
and a root _element_ ("/*"). When you do MoveToRoot on XPathNavigator, you
navigate to the document node, and you'll need to MoveToFirstChild to
position it on the root element. When you deal with an XmlDocument or
XDocument, the document itself is that nameless root document node. However,
when you deal with an XML fragment, there's no document, so the topmost
node - that is, your "root" - becomes the document node for XDM purposes;
except that it doesn't really qualify as such, because the document node is
not supposed to be an element - it has its own distinct type. This seems to
confuse XPath provider here, so "root" ends up matching neither an element
(probably because an element should always have a parent node), nor "/"
(probably because "/" is not supposed to be an element node).
>
If you rewrite your example and make xEl an XDocument, you'll see that it
works as expected (though you'll need to MoveToFirstChild immediately after
MoveToRoot).
>
>
>
Pavel Minaev
Guest
 
Posts: n/a
#5: Sep 6 '08

re: XPathNavigator.Matches doesn't work as I expect


"Anthony Jones" <AnthonyWJones@yadayadayada.comwrote in message
news:e4Dm6y1DJHA.4132@TK2MSFTNGP03.phx.gbl...
Quote:
If this is true its very unsatisfactory. XPath does not define that the
root node should be the Document.
Well, XPath 2.0 does explicitly call that type of node a "document node"
(this of course doesn't mean that it must necessarily be a ***Document class
in .NET). XPath 1.0 calls it a "root node" without further clarification,
but it does specify that it is distinct from element nodes:

http://www.w3.org/TR/xpath#data-model

The tree contains nodes. There are seven types of node:

- root nodes
- element nodes
- text nodes
- attribute nodes
- namespace nodes
- processing instruction nodes
- comment nodes

...

Every node other than the root node has exactly one parent, which is
either an element node or the root node.

...

The root node is the root of the tree. A root node does not occur except
as the root of the tree. The element node for the document element is a
child of the root node. The root node also has as children processing
instruction and comment nodes for processing instructions and comments that
occur in the prolog and after the end of the document element.

...

The root node does not have an expanded-name.

Note that this final requirement clearly marks root node as distinct from
element node. An element node _must_ have a non-empty expanded name (because
you can't have a nameless element in XML).
Quote:
Indeed in many cases its important that it isn't. E.g applying XSL to a
child node in a document should have that child node treated as the root
as far as any XPath present in the XSL is concerned.
The XSLT spec explicitly says that there is always a single root (i.e.,
non-element node) in the source (input) tree, even though it allows that to
have more than one-child (i.e., represent an XML fragment rather than
document), "when the source tree is created in some other way, for example
by using the DOM".


Closed Thread