XPathNavigator.Matches doesn't work as I expect

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?a2FydXpv?=

    XPathNavigator.Matches doesn't work as I expect

    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.CreateNavig ator

    nav.MoveToRoot( )

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

    Console.WriteLi ne("--------------------------")

    nav.MoveToFirst Child()

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

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

    Console.ReadLin e()
  • Pavel Minaev

    #2
    Re: XPathNavigator. Matches doesn't work as I expect


    "karuzo" <karuzo@discuss ions.microsoft. comwrote in message
    news:24F9B3F5-154D-4D74-A7C3-4CBD42230FA5@mi crosoft.com...
    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.CreateNavig ator
    >
    nav.MoveToRoot( )
    >
    Console.WriteLi ne(nav.Matches( "*")) 'returns FALSE
    Console.WriteLi ne(nav.Matches( "root")) 'returns FALSE
    Console.WriteLi ne(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 MoveToFirstChil d 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 MoveToFirstChil d immediately after
    MoveToRoot).


    Comment

    • Anthony Jones

      #3
      Re: XPathNavigator. Matches doesn't work as I expect

      "Pavel Minaev" <int19h@gmail.c omwrote in message
      news:O$s24o1DJH A.3904@TK2MSFTN GP02.phx.gbl...
      >
      "karuzo" <karuzo@discuss ions.microsoft. comwrote in message
      news:24F9B3F5-154D-4D74-A7C3-4CBD42230FA5@mi crosoft.com...
      >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.CreateNavig ator
      >>
      >nav.MoveToRoot ()
      >>
      >Console.WriteL ine(nav.Matches ("*")) 'returns FALSE
      >Console.WriteL ine(nav.Matches ("root")) 'returns FALSE
      >Console.WriteL ine(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
      MoveToFirstChil d 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 MoveToFirstChil d 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

      Comment

      • =?Utf-8?B?a2FydXpv?=

        #4
        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:
        >
        "karuzo" <karuzo@discuss ions.microsoft. comwrote in message
        news:24F9B3F5-154D-4D74-A7C3-4CBD42230FA5@mi crosoft.com...
        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.CreateNavig ator

        nav.MoveToRoot( )

        Console.WriteLi ne(nav.Matches( "*")) 'returns FALSE
        Console.WriteLi ne(nav.Matches( "root")) 'returns FALSE
        Console.WriteLi ne(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 MoveToFirstChil d 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 MoveToFirstChil d immediately after
        MoveToRoot).
        >
        >
        >

        Comment

        • Pavel Minaev

          #5
          Re: XPathNavigator. Matches doesn't work as I expect

          "Anthony Jones" <AnthonyWJones@ yadayadayada.co mwrote in message
          news:e4Dm6y1DJH A.4132@TK2MSFTN GP03.phx.gbl...
          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:

          The World Wide Web Consortium (W3C) is an international community where Member organizations, a full-time staff, and the public work together to develop Web standards.


          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).
          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".


          Comment

          Working...