Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. XPath oddity

XPath oddity

Scheduled Pinned Locked Moved The Weird and The Wonderful
xmllearning
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    PIEBALDconsult
    wrote on last edited by
    #1

    For something I'm working on, I want to test a given XmlElement with a provided XPath predicate to determine whether or not it's the droid node I'm looking for.

    public static bool
    IsMatch
    (
    this System.Xml.XmlElement Element
    ,
    string Predicate
    )
    {
    return ( Element.SelectSingleNode ( "self::node()[" + Predicate + "]" ) != null ) ;
    }

    I wasted an hour trying to get .[predicate] to work.

    System.Xml.XmlDocument doc = new System.Xml.XmlDocument() ;

    doc.LoadXml ( "<Foo Bar='Baz' />" ) ;

    System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( "." ).OuterXml ) ;
    System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( "self::node()[@Bar='Baz']" ).OuterXml ) ;
    System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( "self::*[@Bar='Baz']" ).OuterXml ) ;
    System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( ".[@Bar='Baz']" ).OuterXml ) ;

    <Foo Bar="Baz" />
    <Foo Bar="Baz" />
    <Foo Bar="Baz" />
    System.Xml.XPath.XPathException: '.[@Bar='Baz']' has an invalid token.

    The book I have says . is equivalent to self::node(), but that's not true, . returns a node, whereas self::node() returns a node-set, and you can only apply a predicate to a node-set. :sigh: Of course, if you know of a way to test a node that uses neither SelectSingleNode nor SelectNodes, I'd be glad to see it.

    You'll never get very far if all you do is follow instructions.

    Richard DeemingR 1 Reply Last reply
    0
    • P PIEBALDconsult

      For something I'm working on, I want to test a given XmlElement with a provided XPath predicate to determine whether or not it's the droid node I'm looking for.

      public static bool
      IsMatch
      (
      this System.Xml.XmlElement Element
      ,
      string Predicate
      )
      {
      return ( Element.SelectSingleNode ( "self::node()[" + Predicate + "]" ) != null ) ;
      }

      I wasted an hour trying to get .[predicate] to work.

      System.Xml.XmlDocument doc = new System.Xml.XmlDocument() ;

      doc.LoadXml ( "<Foo Bar='Baz' />" ) ;

      System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( "." ).OuterXml ) ;
      System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( "self::node()[@Bar='Baz']" ).OuterXml ) ;
      System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( "self::*[@Bar='Baz']" ).OuterXml ) ;
      System.Console.WriteLine ( doc.DocumentElement.SelectSingleNode ( ".[@Bar='Baz']" ).OuterXml ) ;

      <Foo Bar="Baz" />
      <Foo Bar="Baz" />
      <Foo Bar="Baz" />
      System.Xml.XPath.XPathException: '.[@Bar='Baz']' has an invalid token.

      The book I have says . is equivalent to self::node(), but that's not true, . returns a node, whereas self::node() returns a node-set, and you can only apply a predicate to a node-set. :sigh: Of course, if you know of a way to test a node that uses neither SelectSingleNode nor SelectNodes, I'd be glad to see it.

      You'll never get very far if all you do is follow instructions.

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      PIEBALDconsult wrote:

      Of course, if you know of a way to test a node that uses neither SelectSingleNode nor SelectNodes, I'd be glad to see it.

      How about this?

      public static bool IsMatch(this System.Xml.XmlElement element, string predicate)
      {
      return element.CreateNavigator().Matches("*[" + predicate + "]");
      }

      If you're going to be re-using the same predicate for a lot of elements, you might want to pre-compile it[^]:

      public static bool IsMatch(this System.Xml.XmlElement element, XPathExpression compiledPredicate)
      {
      return element.CreateNavigator().Matches(compiledPredicate);
      }
      ...
      var compiledPredicate = XPathExpression.Compile("*[" + predicate + "]");


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      P 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        PIEBALDconsult wrote:

        Of course, if you know of a way to test a node that uses neither SelectSingleNode nor SelectNodes, I'd be glad to see it.

        How about this?

        public static bool IsMatch(this System.Xml.XmlElement element, string predicate)
        {
        return element.CreateNavigator().Matches("*[" + predicate + "]");
        }

        If you're going to be re-using the same predicate for a lot of elements, you might want to pre-compile it[^]:

        public static bool IsMatch(this System.Xml.XmlElement element, XPathExpression compiledPredicate)
        {
        return element.CreateNavigator().Matches(compiledPredicate);
        }
        ...
        var compiledPredicate = XPathExpression.Compile("*[" + predicate + "]");


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        P Offline
        P Offline
        PIEBALDconsult
        wrote on last edited by
        #3

        Thanks, I'll try that too and maybe do some performance comparisons. Performance really isn't an issue with my current usage -- about forty elements being checked with a predicate provided on the command-line. Your second implementation might make for the basis of an enumerator. :thumbsup:

        You'll never get very far if all you do is follow instructions.

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups