Simple Xpath question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ot

    Simple Xpath question

    I posted this to the wrong group. It went to m.p.dotnet.lang uages.vb.
    Ooops.

    --------------------------------------------------------------------

    I have this tiny problem. I have learned that an xpath expression can be
    bounded by either single or double quotation marks.

    But sometimes I want to search for a title containing both a single and
    double quote. Any way to do this?

    The user enters the title, so now it is in a String variable.

    How can I dynamically construct the right Xpath query to find the book with
    that title.

    <book>
    <title>Who's your "Daddy"</title>


    The only logic that I can think of is to detect the occurrence of double
    quotes in the data and make an iterator that finds the partial title (the
    part that doesn't contain the ' " ') and then do an individual match title
    by title.


  • Martin Honnen

    #2
    Re: Simple Xpath question



    Ot wrote:

    [color=blue]
    > I have this tiny problem. I have learned that an xpath expression can be
    > bounded by either single or double quotation marks.
    >
    > But sometimes I want to search for a title containing both a single and
    > double quote. Any way to do this?
    >
    > The user enters the title, so now it is in a String variable.
    >
    > How can I dynamically construct the right Xpath query to find the book with
    > that title.
    >
    > <book>
    > <title>Who's your "Daddy"</title>
    >
    >
    > The only logic that I can think of is to detect the occurrence of double
    > quotes in the data and make an iterator that finds the partial title (the
    > part that doesn't contain the ' " ') and then do an individual match title
    > by title.[/color]

    Here is an example C# program that breaks up a string as needed to
    construct an XPath concat function call

    using System;
    using System.Xml;

    public class Test20040125 {
    public static void Main (string[] args) {
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.Loa dXml(
    @"<book><title> Who's your ""Daddy""</title></book>");
    string userInput = @"Who's your ""Daddy""";
    XmlElement title = xmlDocument.Sel ectSingleNode("//title[. = " +
    buildXPathStrin g(userInput) + "]") as XmlElement;
    if (title != null) {
    Console.WriteLi ne(title.OuterX ml);
    }
    else {
    Console.WriteLi ne("No element found.");
    }
    }

    public static string buildXPathStrin g (string input) {
    string[] components = input.Split(new char[] { '\''});
    string result = "";
    result += "concat(''" ;
    for (int i = 0; i < components.Leng th; i++) {
    result += ", '" + components[i] + "'";
    if (i < components.Leng th - 1) {
    result += ", \"'\"";
    }
    }
    result += ")";
    Console.WriteLi ne(result);
    return result;
    }
    }


    The example constructs
    concat('', 'Who', "'", 's your "Daddy"')
    as the XPath concat call so you see that the string is split up into
    parts not containing a single quote and parts just containing the single
    quote.
    --

    Martin Honnen


    Comment

    • Ot

      #3
      Re: Simple Xpath question (html for readability)

      "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message news:%23PzSut14 DHA.2392@TK2MSF TNGP11.phx.gbl. ..[color=blue]
      >
      > Here is an example C# program that breaks up a string as needed to
      > construct an XPath concat function call
      >
      > using System;
      > using System.Xml;
      >
      > public class Test20040125 {
      > public static void Main (string[] args) {
      > XmlDocument xmlDocument = new XmlDocument();
      > xmlDocument.Loa dXml(
      > @"<book><title> Who's your ""Daddy""</title></book>");
      > string userInput = @"Who's your ""Daddy""";
      > XmlElement title = xmlDocument.Sel ectSingleNode("//title[. = " +
      > buildXPathStrin g(userInput) + "]") as XmlElement;
      > if (title != null) {
      > Console.WriteLi ne(title.OuterX ml);
      > }
      > else {
      > Console.WriteLi ne("No element found.");
      > }
      > }
      >
      > public static string buildXPathStrin g (string input) {
      > string[] components = input.Split(new char[] { '\''});
      > string result = "";
      > result += "concat(''" ;
      > for (int i = 0; i < components.Leng th; i++) {
      > result += ", '" + components[i] + "'";
      > if (i < components.Leng th - 1) {
      > result += ", \"'\"";
      > }
      > }
      > result += ")";
      > Console.WriteLi ne(result);
      > return result;
      > }
      > }
      >
      >
      > The example constructs
      > concat('', 'Who', "'", 's your "Daddy"')
      > as the XPath concat call so you see that the string is split up into
      > parts not containing a single quote and parts just containing the single
      > quote.
      > --
      >
      > Martin Honnen
      > http://JavaScript.FAQTs.com/
      > [/color]

      Thanks for your input. I did my best to reconstruct what you wrote in an equivalent VB.NET program. (I made it react to a button-click, but it is really no different.) Thing is, it gets an exception. Can you figure out why? I'm really confused here.

      \\\
      Private Sub Button1_Click(B yVal sender As Object, ByVal e As System.EventArg s) Handles Button1.Click
      Dim xmlDocument As XmlDocument = New XmlDocument
      xmlDocument.Loa dXml("<book><ti tle>Who's your ""Daddy""</title></book>")
      Dim sw As IO.StreamWriter = New System.IO.Strea mWriter("C:\tes tbook.xml")
      Dim xm As System.Xml.XmlT extWriter = New System.Xml.XmlT extWriter(sw)
      xm.Formatting = Formatting.Inde nted
      xm.Indentation = 2
      xm.IndentChar = " "
      xmlDocument.Sav e(xm)
      Dim userInput As String = "Who's your ""Daddy"""
      Dim query As String = "//title[. = '" & buildXpathStrin g(userInput) & "']"
      Console.WriteLi ne("query={" & query & "}")
      Dim title As XmlElement = _
      xmlDocument.Sel ectSingleNode(q uery)
      If title Is Nothing Then
      Console.WriteLi ne("No Element found.")
      Else
      Console.WriteLi ne("Title=" & title.OuterXml)
      End If
      End Sub
      Function buildXpathStrin g(ByVal input As String) As String
      Dim components() As String = input.Split("'" c)
      Dim result As String = ""
      For i As Integer = 0 To components.Leng th - 2
      result += components(i) & "''"
      Next
      result += components(comp onents.Length - 1)
      Console.WriteLi ne("result={" & result & "}")
      Return result
      End Function
      ///

      has as output

      \\\
      result={Who''s your "Daddy"}
      query={//title[. = 'Who''s your "Daddy"']}
      An unhandled exception of type 'System.Xml.XPa th.XPathExcepti on' occurred in system.xml.dll
      Additional information: System error.
      Unhandled Exception: System.Xml.XPat h.XPathExceptio n: '//title[. = 'Who''s your "Daddy"']' has an invalid token.
      ///

      The contents of testbook.xml file is

      \\\
      <?xml version="1.0" encoding="utf-8"?>
      <book>
      <title>Who's your "Daddy"</title>
      </book>
      ///

      Comment

      • Ot

        #4
        Re: Simple Xpath question


        "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message
        news:%23PzSut14 DHA.2392@TK2MSF TNGP11.phx.gbl. ..[color=blue]
        >
        >
        > Ot wrote:
        >
        >[color=green]
        > > I have this tiny problem. I have learned that an xpath expression can[/color][/color]
        be[color=blue][color=green]
        > > bounded by either single or double quotation marks.
        > >
        > > But sometimes I want to search for a title containing both a single and
        > > double quote. Any way to do this?
        > >
        > > The user enters the title, so now it is in a String variable.
        > >
        > > How can I dynamically construct the right Xpath query to find the book[/color][/color]
        with[color=blue][color=green]
        > > that title.
        > >
        > > <book>
        > > <title>Who's your "Daddy"</title>
        > >
        > >
        > > The only logic that I can think of is to detect the occurrence of[/color][/color]
        double[color=blue][color=green]
        > > quotes in the data and make an iterator that finds the partial title[/color][/color]
        (the[color=blue][color=green]
        > > part that doesn't contain the ' " ') and then do an individual match[/color][/color]
        title[color=blue][color=green]
        > > by title.[/color]
        >
        > Here is an example C# program that breaks up a string as needed to
        > construct an XPath concat function call
        >
        > using System;
        > using System.Xml;
        >
        > public class Test20040125 {
        > public static void Main (string[] args) {
        > XmlDocument xmlDocument = new XmlDocument();
        > xmlDocument.Loa dXml(
        > @"<book><title> Who's your ""Daddy""</title></book>");
        > string userInput = @"Who's your ""Daddy""";
        > XmlElement title = xmlDocument.Sel ectSingleNode("//title[. = " +
        > buildXPathStrin g(userInput) + "]") as XmlElement;
        > if (title != null) {
        > Console.WriteLi ne(title.OuterX ml);
        > }
        > else {
        > Console.WriteLi ne("No element found.");
        > }
        > }
        >
        > public static string buildXPathStrin g (string input) {
        > string[] components = input.Split(new char[] { '\''});
        > string result = "";
        > result += "concat(''" ;
        > for (int i = 0; i < components.Leng th; i++) {
        > result += ", '" + components[i] + "'";
        > if (i < components.Leng th - 1) {
        > result += ", \"'\"";
        > }
        > }
        > result += ")";
        > Console.WriteLi ne(result);
        > return result;
        > }
        > }
        >
        >
        > The example constructs
        > concat('', 'Who', "'", 's your "Daddy"')
        > as the XPath concat call so you see that the string is split up into
        > parts not containing a single quote and parts just containing the single
        > quote.
        > --
        >
        > Martin Honnen
        > http://JavaScript.FAQTs.com/
        >[/color]

        Thanks for your input. I did my best to reconstruct what you wrote in an
        equivalent VB.NET program. (I made it react to a button-click, but it is
        really no different.) Thing is, it gets an exception. Can you figure out
        why? I'm really confused here.

        \\\
        Private Sub Button1_Click(B yVal sender As Object, ByVal e As
        System.EventArg s) Handles Button1.Click
        Dim xmlDocument As XmlDocument = New XmlDocument
        xmlDocument.Loa dXml("<book><ti tle>Who's your
        ""Daddy""</title></book>")
        Dim sw As IO.StreamWriter = New
        System.IO.Strea mWriter("C:\tes tbook.xml")
        Dim xm As System.Xml.XmlT extWriter = New
        System.Xml.XmlT extWriter(sw)
        xm.Formatting = Formatting.Inde nted
        xm.Indentation = 2
        xm.IndentChar = " "
        xmlDocument.Sav e(xm)
        Dim userInput As String = "Who's your ""Daddy"""
        Dim query As String = "//title[. = '" & buildXpathStrin g(userInput)
        & "']"
        Console.WriteLi ne("query={" & query & "}")
        Dim title As XmlElement = _
        xmlDocument.Sel ectSingleNode(q uery)
        If title Is Nothing Then
        Console.WriteLi ne("No Element found.")
        Else
        Console.WriteLi ne("Title=" & title.OuterXml)
        End If
        End Sub
        Function buildXpathStrin g(ByVal input As String) As String
        Dim components() As String = input.Split("'" c)
        Dim result As String = ""
        For i As Integer = 0 To components.Leng th - 2
        result += components(i) & "''"
        Next
        result += components(comp onents.Length - 1)
        Console.WriteLi ne("result={" & result & "}")
        Return result
        End Function
        ///

        has as output

        \\\
        result={Who''s your "Daddy"}
        query={//title[. = 'Who''s your "Daddy"']}
        An unhandled exception of type 'System.Xml.XPa th.XPathExcepti on' occurred
        in system.xml.dll
        Additional information: System error.
        Unhandled Exception: System.Xml.XPat h.XPathExceptio n: '//title[. = 'Who''s
        your "Daddy"']' has an invalid token.
        ///

        The contents of testbook.xml file is

        \\\
        <?xml version="1.0" encoding="utf-8"?>
        <book>
        <title>Who's your "Daddy"</title>
        </book>
        ///


        Comment

        • Martin Honnen

          #5
          Re: Simple Xpath question



          Ot wrote:
          [color=blue]
          > "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message[/color]
          [color=blue][color=green]
          >>Here is an example C# program that breaks up a string as needed to
          >>construct an XPath concat function call
          >>
          >>using System;
          >>using System.Xml;
          >>
          >>public class Test20040125 {
          >> public static void Main (string[] args) {
          >> XmlDocument xmlDocument = new XmlDocument();
          >> xmlDocument.Loa dXml(
          >>@"<book><titl e>Who's your ""Daddy""</title></book>");
          >> string userInput = @"Who's your ""Daddy""";
          >> XmlElement title = xmlDocument.Sel ectSingleNode("//title[. = " +
          >>buildXPathStr ing(userInput) + "]") as XmlElement;
          >> if (title != null) {
          >> Console.WriteLi ne(title.OuterX ml);
          >> }
          >> else {
          >> Console.WriteLi ne("No element found.");
          >> }
          >> }
          >>
          >> public static string buildXPathStrin g (string input) {
          >> string[] components = input.Split(new char[] { '\''});
          >> string result = "";
          >> result += "concat(''" ;
          >> for (int i = 0; i < components.Leng th; i++) {
          >> result += ", '" + components[i] + "'";
          >> if (i < components.Leng th - 1) {
          >> result += ", \"'\"";
          >> }
          >> }
          >> result += ")";
          >> Console.WriteLi ne(result);
          >> return result;
          >> }
          >>}
          >>
          >>
          >>The example constructs
          >> concat('', 'Who', "'", 's your "Daddy"')
          >>as the XPath concat call so you see that the string is split up into
          >>parts not containing a single quote and parts just containing the single
          >>quote.[/color][/color]
          [color=blue]
          >
          > Thanks for your input. I did my best to reconstruct what you wrote in an
          > equivalent VB.NET program. (I made it react to a button-click, but it is
          > really no different.) Thing is, it gets an exception. Can you figure out
          > why? I'm really confused here.
          >[/color]
          [color=blue]
          > Function buildXpathStrin g(ByVal input As String) As String
          > Dim components() As String = input.Split("'" c)
          > Dim result As String = ""
          > For i As Integer = 0 To components.Leng th - 2
          > result += components(i) & "''"
          > Next
          > result += components(comp onents.Length - 1)
          > Console.WriteLi ne("result={" & result & "}")
          > Return result
          > End Function[/color]

          The suggested solution is to construct some XPath expression with a
          concat(...)
          function call which the C# method above does while your VB.NET method
          doesn't do that.
          --

          Martin Honnen


          Comment

          • Ot

            #6
            Re: Simple Xpath question


            "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message
            news:eehOoQC5DH A.1636@TK2MSFTN GP12.phx.gbl...[color=blue]
            >[color=green]
            > > The suggested solution is to construct some XPath expression with a[/color]
            > concat(...)
            > function call which the C# method above does while your VB.NET method
            > doesn't do that.
            > --
            >
            > Martin Honnen
            > http://JavaScript.FAQTs.com/
            >[/color]

            Forgive my confusion, but isn't a string a string regardless of how it is
            constructed? Isn't this an Xpath issue now, not a programming issue?
            Doesn't your C# program eventually issue the same Xpath query? It seems to
            me it does, hence my confusion.

            As you can see from my quoted output I get

            query={//title[. = 'Who''s your "Daddy"']}

            (the '{' and '}' I put in just to show the extent of the string, they are
            not part of the string itself.)

            then I do

            Dim title As XmlElement = _
            xmlDocument.Sel ectSingleNode(q uery)

            and the error occurs.

            Thanks for taking your time to help me with this, it is appreciated.


            Comment

            • Martin Honnen

              #7
              Re: Simple Xpath question



              Ot wrote:
              [color=blue]
              > "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message
              > news:eehOoQC5DH A.1636@TK2MSFTN GP12.phx.gbl...
              >[color=green][color=darkred]
              >>>The suggested solution is to construct some XPath expression with a[/color]
              >>
              >> concat(...)
              >>function call which the C# method above does while your VB.NET method
              >>doesn't do that.[/color][/color]
              [color=blue]
              >
              > Forgive my confusion, but isn't a string a string regardless of how it is
              > constructed? Isn't this an Xpath issue now, not a programming issue?
              > Doesn't your C# program eventually issue the same Xpath query? It seems to
              > me it does, hence my confusion.
              >
              > As you can see from my quoted output I get
              >
              > query={//title[. = 'Who''s your "Daddy"']}[/color]

              Yes, but that doesn't work, you need to construct the XPath expression
              //title[. = concat('Who', "'", 's your "Daddy"')]
              --

              Martin Honnen


              Comment

              • Ot

                #8
                Re: Simple Xpath question


                "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message
                news:eeP1tUD5DH A.2656@TK2MSFTN GP11.phx.gbl...[color=blue]
                >
                >
                > Ot wrote:
                >[color=green]
                > > "Martin Honnen" <Martin.Honnen@ t-online.de> wrote in message
                > > news:eehOoQC5DH A.1636@TK2MSFTN GP12.phx.gbl...
                > >[color=darkred]
                > >>>The suggested solution is to construct some XPath expression with a
                > >>
                > >> concat(...)
                > >>function call which the C# method above does while your VB.NET method
                > >>doesn't do that.[/color][/color]
                >[color=green]
                > >
                > > Forgive my confusion, but isn't a string a string regardless of how it[/color][/color]
                is[color=blue][color=green]
                > > constructed? Isn't this an Xpath issue now, not a programming issue?
                > > Doesn't your C# program eventually issue the same Xpath query? It[/color][/color]
                seems to[color=blue][color=green]
                > > me it does, hence my confusion.
                > >
                > > As you can see from my quoted output I get
                > >
                > > query={//title[. = 'Who''s your "Daddy"']}[/color]
                >
                > Yes, but that doesn't work, you need to construct the XPath expression
                > //title[. = concat('Who', "'", 's your "Daddy"')]
                > --
                >
                > Martin Honnen
                > http://JavaScript.FAQTs.com/
                >[/color]

                Ah, dawns the light!

                Thanks for your help!


                Comment

                Working...