Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old February 25th, 2006, 11:25 PM
David Thielen
Guest
 
Posts: n/a
Default Why does this xpath fail - starting over

Hi;

I am sure I am missing something here but I cannot figure it out. Below I
have a program and I cannot figure out why the xpath selects that throw an
exception fail. From what I know they should work.

Also the second nav.OuterXml appears to also be wrong to me.

Can someone explain to me why this does not work? (This is an example from a
program we have where xpath can be entered in two parts so we have to be able
to handle this. We can't just always require the fill
/order/product[.='software'].)

Program below sig.

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com

Program.cs:
using System.Xml;
using System.Xml.XPath;
using System;
using System.IO;

namespace XPathSample
{
class Program
{
static void Main(string[] args)
{

string xml =
"<order>" +
"<product>software</product>" +
"<product>software</product>" +
"</order>";
XPathDocument doc = new XPathDocument(new StringReader(xml));

// this works
XPathNavigator nav = doc.CreateNavigator();
XPathNavigator rtn = nav.SelectSingleNode("/order/product[.='software']");
Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
Console.Out.WriteLine("/order/product[.='software'] = " + rtn.OuterXml);

// this works although the nav.OuterXml appears wrong
nav = nav.SelectSingleNode("/order");
rtn = nav.SelectSingleNode("product[.='software']");
Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);

// this works (same as prev)
rtn = nav.SelectSingleNode("./product[.='software']");
Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);

nav = nav.SelectSingleNode("product");
Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);

// these all fail - WHY?
try
{
rtn = nav.SelectSingleNode("[.='software']");
}
catch (XPathException ex)
{
Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
}
try
{
rtn = nav.SelectSingleNode("./[.='software']");
}
catch (XPathException ex)
{
Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
}

// yes this works - but I need the node as it does have a value.
object obj = nav.Evaluate(".='software'");
Console.Out.WriteLine(".='software' evaluate = " + obj);


Console.Out.WriteLine("all done");
}
}
}


  #2  
Old February 26th, 2006, 06:55 AM
Dimitre Novatchev
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over

> // these all fail - WHY?

because of a common feature -- they all have invalid XPath syntax.
[color=blue]
> try
> {
> rtn = nav.SelectSingleNode("[.='software']");
> }
> catch (XPathException ex)
> {
> Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> }
> try
> {
> rtn = nav.SelectSingleNode("./[.='software']");
> }
> catch (XPathException ex)
> {
> Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> }
>
> // yes this works - but I need the node as it does have a value.
> object obj = nav.Evaluate(".='software'");
> Console.Out.WriteLine(".='software' evaluate = " + obj);[/color]


Try:

"self::*[.='software']"

or

"string(self::*[.='software'])"

depending on whether you need the node or its string value returned.


Cheers,
Dimitre Novatchev





"David Thielen" <david@bogus.windward.net> wrote in message
news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...[color=blue]
> Hi;
>
> I am sure I am missing something here but I cannot figure it out. Below I
> have a program and I cannot figure out why the xpath selects that throw an
> exception fail. From what I know they should work.
>
> Also the second nav.OuterXml appears to also be wrong to me.
>
> Can someone explain to me why this does not work? (This is an example from
> a
> program we have where xpath can be entered in two parts so we have to be
> able
> to handle this. We can't just always require the fill
> /order/product[.='software'].)
>
> Program below sig.
>
> --
> thanks - dave
> david_at_windward_dot_net
> http://www.windwardreports.com
>
> Program.cs:
> using System.Xml;
> using System.Xml.XPath;
> using System;
> using System.IO;
>
> namespace XPathSample
> {
> class Program
> {
> static void Main(string[] args)
> {
>
> string xml =
> "<order>" +
> "<product>software</product>" +
> "<product>software</product>" +
> "</order>";
> XPathDocument doc = new XPathDocument(new StringReader(xml));
>
> // this works
> XPathNavigator nav = doc.CreateNavigator();
> XPathNavigator rtn = nav.SelectSingleNode("/order/product[.='software']");
> Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
> Console.Out.WriteLine("/order/product[.='software'] = " + rtn.OuterXml);
>
> // this works although the nav.OuterXml appears wrong
> nav = nav.SelectSingleNode("/order");
> rtn = nav.SelectSingleNode("product[.='software']");
> Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
> Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
>
> // this works (same as prev)
> rtn = nav.SelectSingleNode("./product[.='software']");
> Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);
>
> nav = nav.SelectSingleNode("product");
> Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
>
> // these all fail - WHY?
> try
> {
> rtn = nav.SelectSingleNode("[.='software']");
> }
> catch (XPathException ex)
> {
> Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> }
> try
> {
> rtn = nav.SelectSingleNode("./[.='software']");
> }
> catch (XPathException ex)
> {
> Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> }
>
> // yes this works - but I need the node as it does have a value.
> object obj = nav.Evaluate(".='software'");
> Console.Out.WriteLine(".='software' evaluate = " + obj);
>
>
> Console.Out.WriteLine("all done");
> }
> }
> }
>
>[/color]


  #3  
Old February 27th, 2006, 12:55 AM
David Thielen
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over

Hello;

I assumed it is invalid syntax. My question is why? I don't understand why
"[.='software']" or some variation of that is invalid.

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com



"Dimitre Novatchev" wrote:
[color=blue][color=green]
> > // these all fail - WHY?[/color]
>
> because of a common feature -- they all have invalid XPath syntax.
>[color=green]
> > try
> > {
> > rtn = nav.SelectSingleNode("[.='software']");
> > }
> > catch (XPathException ex)
> > {
> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> > }
> > try
> > {
> > rtn = nav.SelectSingleNode("./[.='software']");
> > }
> > catch (XPathException ex)
> > {
> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> > }
> >
> > // yes this works - but I need the node as it does have a value.
> > object obj = nav.Evaluate(".='software'");
> > Console.Out.WriteLine(".='software' evaluate = " + obj);[/color]
>
>
> Try:
>
> "self::*[.='software']"
>
> or
>
> "string(self::*[.='software'])"
>
> depending on whether you need the node or its string value returned.
>
>
> Cheers,
> Dimitre Novatchev
>
>
>
>
>
> "David Thielen" <david@bogus.windward.net> wrote in message
> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...[color=green]
> > Hi;
> >
> > I am sure I am missing something here but I cannot figure it out. Below I
> > have a program and I cannot figure out why the xpath selects that throw an
> > exception fail. From what I know they should work.
> >
> > Also the second nav.OuterXml appears to also be wrong to me.
> >
> > Can someone explain to me why this does not work? (This is an example from
> > a
> > program we have where xpath can be entered in two parts so we have to be
> > able
> > to handle this. We can't just always require the fill
> > /order/product[.='software'].)
> >
> > Program below sig.
> >
> > --
> > thanks - dave
> > david_at_windward_dot_net
> > http://www.windwardreports.com
> >
> > Program.cs:
> > using System.Xml;
> > using System.Xml.XPath;
> > using System;
> > using System.IO;
> >
> > namespace XPathSample
> > {
> > class Program
> > {
> > static void Main(string[] args)
> > {
> >
> > string xml =
> > "<order>" +
> > "<product>software</product>" +
> > "<product>software</product>" +
> > "</order>";
> > XPathDocument doc = new XPathDocument(new StringReader(xml));
> >
> > // this works
> > XPathNavigator nav = doc.CreateNavigator();
> > XPathNavigator rtn = nav.SelectSingleNode("/order/product[.='software']");
> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
> > Console.Out.WriteLine("/order/product[.='software'] = " + rtn.OuterXml);
> >
> > // this works although the nav.OuterXml appears wrong
> > nav = nav.SelectSingleNode("/order");
> > rtn = nav.SelectSingleNode("product[.='software']");
> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
> >
> > // this works (same as prev)
> > rtn = nav.SelectSingleNode("./product[.='software']");
> > Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);
> >
> > nav = nav.SelectSingleNode("product");
> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
> >
> > // these all fail - WHY?
> > try
> > {
> > rtn = nav.SelectSingleNode("[.='software']");
> > }
> > catch (XPathException ex)
> > {
> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> > }
> > try
> > {
> > rtn = nav.SelectSingleNode("./[.='software']");
> > }
> > catch (XPathException ex)
> > {
> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> > }
> >
> > // yes this works - but I need the node as it does have a value.
> > object obj = nav.Evaluate(".='software'");
> > Console.Out.WriteLine(".='software' evaluate = " + obj);
> >
> >
> > Console.Out.WriteLine("all done");
> > }
> > }
> > }
> >
> >[/color]
>
>
>[/color]
  #4  
Old February 27th, 2006, 07:15 AM
Dimitre Novatchev
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over


"David Thielen" <david@bogus.windward.net> wrote in message
news:24EA7468-C52A-4765-B556-1EE1DCF81F1B@microsoft.com...[color=blue]
> Hello;
>
> I assumed it is invalid syntax. My question is why? I don't understand why
> "[.='software']" or some variation of that is invalid.[/color]

Read the XPath 1.0 Spec.

It says:

http://www.w3.org/TR/xpath#predicates

"A predicate filters a node-set with respect to an axis to produce a new
node-set. For each node in the node-set to be filtered, the PredicateExpr is
evaluated with that node as the context node, with the number of nodes in
the node-set as the context size, and with the proximity position of the
node in the node-set with respect to the axis as the context position; if
PredicateExpr evaluates to true for that node, the node is included in the
new node-set; otherwise, it is not included."



So, a predicate can only apear after some XPath expression and filters it. A
predicate, alone, is not a valid XPath expression.

This is also made clear if we look at the BNF grammar definition of XPath
1.0. Of all rules only rule [4] and rule [20] contain the nonterminal symbol
predicate and it is always not the leading symbol (of the RHS):



http://www.w3.org/TR/xpath#section-Location-Steps


[4] Step ::= AxisSpecifier NodeTest Predicate*
| AbbreviatedStep




http://www.w3.org/TR/xpath#node-sets



[20] FilterExpr ::= PrimaryExpr
| FilterExpr Predicate




I hope that this answers completely your question.


Cheers,
Dimitre Novatchev


[color=blue]
>
> --
> thanks - dave
> david_at_windward_dot_net
> http://www.windwardreports.com
>
>
>
> "Dimitre Novatchev" wrote:
>[color=green][color=darkred]
>> > // these all fail - WHY?[/color]
>>
>> because of a common feature -- they all have invalid XPath syntax.
>>[color=darkred]
>> > try
>> > {
>> > rtn = nav.SelectSingleNode("[.='software']");
>> > }
>> > catch (XPathException ex)
>> > {
>> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
>> > }
>> > try
>> > {
>> > rtn = nav.SelectSingleNode("./[.='software']");
>> > }
>> > catch (XPathException ex)
>> > {
>> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
>> > }
>> >
>> > // yes this works - but I need the node as it does have a value.
>> > object obj = nav.Evaluate(".='software'");
>> > Console.Out.WriteLine(".='software' evaluate = " + obj);[/color]
>>
>>
>> Try:
>>
>> "self::*[.='software']"
>>
>> or
>>
>> "string(self::*[.='software'])"
>>
>> depending on whether you need the node or its string value returned.
>>
>>
>> Cheers,
>> Dimitre Novatchev
>>
>>
>>
>>
>>
>> "David Thielen" <david@bogus.windward.net> wrote in message
>> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...[color=darkred]
>> > Hi;
>> >
>> > I am sure I am missing something here but I cannot figure it out. Below
>> > I
>> > have a program and I cannot figure out why the xpath selects that throw
>> > an
>> > exception fail. From what I know they should work.
>> >
>> > Also the second nav.OuterXml appears to also be wrong to me.
>> >
>> > Can someone explain to me why this does not work? (This is an example
>> > from
>> > a
>> > program we have where xpath can be entered in two parts so we have to
>> > be
>> > able
>> > to handle this. We can't just always require the fill
>> > /order/product[.='software'].)
>> >
>> > Program below sig.
>> >
>> > --
>> > thanks - dave
>> > david_at_windward_dot_net
>> > http://www.windwardreports.com
>> >
>> > Program.cs:
>> > using System.Xml;
>> > using System.Xml.XPath;
>> > using System;
>> > using System.IO;
>> >
>> > namespace XPathSample
>> > {
>> > class Program
>> > {
>> > static void Main(string[] args)
>> > {
>> >
>> > string xml =
>> > "<order>" +
>> > "<product>software</product>" +
>> > "<product>software</product>" +
>> > "</order>";
>> > XPathDocument doc = new XPathDocument(new StringReader(xml));
>> >
>> > // this works
>> > XPathNavigator nav = doc.CreateNavigator();
>> > XPathNavigator rtn =
>> > nav.SelectSingleNode("/order/product[.='software']");
>> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
>> > Console.Out.WriteLine("/order/product[.='software'] = " +
>> > rtn.OuterXml);
>> >
>> > // this works although the nav.OuterXml appears wrong
>> > nav = nav.SelectSingleNode("/order");
>> > rtn = nav.SelectSingleNode("product[.='software']");
>> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
>> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
>> >
>> > // this works (same as prev)
>> > rtn = nav.SelectSingleNode("./product[.='software']");
>> > Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);
>> >
>> > nav = nav.SelectSingleNode("product");
>> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
>> >
>> > // these all fail - WHY?
>> > try
>> > {
>> > rtn = nav.SelectSingleNode("[.='software']");
>> > }
>> > catch (XPathException ex)
>> > {
>> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
>> > }
>> > try
>> > {
>> > rtn = nav.SelectSingleNode("./[.='software']");
>> > }
>> > catch (XPathException ex)
>> > {
>> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
>> > }
>> >
>> > // yes this works - but I need the node as it does have a value.
>> > object obj = nav.Evaluate(".='software'");
>> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >
>> >
>> > Console.Out.WriteLine("all done");
>> > }
>> > }
>> > }
>> >
>> >[/color]
>>
>>
>>[/color][/color]



  #5  
Old February 27th, 2006, 06:25 PM
David Thielen
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over

Hi;

First, thanks for helping on this I really appreciate it.

Ok, I see that the xpath must start with "." to get it to the node and the
"[...]" then modifies that - makes sense.

But then, shouldn't ".[.='software']" or "./.[.='software']" or
"./[.='software']" work.

In the case of ".[.='software']" isn't that saying start with the node "."
(which exists) and then return all where .='software'?

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com



"Dimitre Novatchev" wrote:
[color=blue]
>
> "David Thielen" <david@bogus.windward.net> wrote in message
> news:24EA7468-C52A-4765-B556-1EE1DCF81F1B@microsoft.com...[color=green]
> > Hello;
> >
> > I assumed it is invalid syntax. My question is why? I don't understand why
> > "[.='software']" or some variation of that is invalid.[/color]
>
> Read the XPath 1.0 Spec.
>
> It says:
>
> http://www.w3.org/TR/xpath#predicates
>
> "A predicate filters a node-set with respect to an axis to produce a new
> node-set. For each node in the node-set to be filtered, the PredicateExpr is
> evaluated with that node as the context node, with the number of nodes in
> the node-set as the context size, and with the proximity position of the
> node in the node-set with respect to the axis as the context position; if
> PredicateExpr evaluates to true for that node, the node is included in the
> new node-set; otherwise, it is not included."
>
>
>
> So, a predicate can only apear after some XPath expression and filters it. A
> predicate, alone, is not a valid XPath expression.
>
> This is also made clear if we look at the BNF grammar definition of XPath
> 1.0. Of all rules only rule [4] and rule [20] contain the nonterminal symbol
> predicate and it is always not the leading symbol (of the RHS):
>
>
>
> http://www.w3.org/TR/xpath#section-Location-Steps
>
>
> [4] Step ::= AxisSpecifier NodeTest Predicate*
> | AbbreviatedStep
>
>
>
>
> http://www.w3.org/TR/xpath#node-sets
>
>
>
> [20] FilterExpr ::= PrimaryExpr
> | FilterExpr Predicate
>
>
>
>
> I hope that this answers completely your question.
>
>
> Cheers,
> Dimitre Novatchev
>
>
>[color=green]
> >
> > --
> > thanks - dave
> > david_at_windward_dot_net
> > http://www.windwardreports.com
> >
> >
> >
> > "Dimitre Novatchev" wrote:
> >[color=darkred]
> >> > // these all fail - WHY?
> >>
> >> because of a common feature -- they all have invalid XPath syntax.
> >>
> >> > try
> >> > {
> >> > rtn = nav.SelectSingleNode("[.='software']");
> >> > }
> >> > catch (XPathException ex)
> >> > {
> >> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> >> > }
> >> > try
> >> > {
> >> > rtn = nav.SelectSingleNode("./[.='software']");
> >> > }
> >> > catch (XPathException ex)
> >> > {
> >> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> >> > }
> >> >
> >> > // yes this works - but I need the node as it does have a value.
> >> > object obj = nav.Evaluate(".='software'");
> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
> >>
> >>
> >> Try:
> >>
> >> "self::*[.='software']"
> >>
> >> or
> >>
> >> "string(self::*[.='software'])"
> >>
> >> depending on whether you need the node or its string value returned.
> >>
> >>
> >> Cheers,
> >> Dimitre Novatchev
> >>
> >>
> >>
> >>
> >>
> >> "David Thielen" <david@bogus.windward.net> wrote in message
> >> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...
> >> > Hi;
> >> >
> >> > I am sure I am missing something here but I cannot figure it out. Below
> >> > I
> >> > have a program and I cannot figure out why the xpath selects that throw
> >> > an
> >> > exception fail. From what I know they should work.
> >> >
> >> > Also the second nav.OuterXml appears to also be wrong to me.
> >> >
> >> > Can someone explain to me why this does not work? (This is an example
> >> > from
> >> > a
> >> > program we have where xpath can be entered in two parts so we have to
> >> > be
> >> > able
> >> > to handle this. We can't just always require the fill
> >> > /order/product[.='software'].)
> >> >
> >> > Program below sig.
> >> >
> >> > --
> >> > thanks - dave
> >> > david_at_windward_dot_net
> >> > http://www.windwardreports.com
> >> >
> >> > Program.cs:
> >> > using System.Xml;
> >> > using System.Xml.XPath;
> >> > using System;
> >> > using System.IO;
> >> >
> >> > namespace XPathSample
> >> > {
> >> > class Program
> >> > {
> >> > static void Main(string[] args)
> >> > {
> >> >
> >> > string xml =
> >> > "<order>" +
> >> > "<product>software</product>" +
> >> > "<product>software</product>" +
> >> > "</order>";
> >> > XPathDocument doc = new XPathDocument(new StringReader(xml));
> >> >
> >> > // this works
> >> > XPathNavigator nav = doc.CreateNavigator();
> >> > XPathNavigator rtn =
> >> > nav.SelectSingleNode("/order/product[.='software']");
> >> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
> >> > Console.Out.WriteLine("/order/product[.='software'] = " +
> >> > rtn.OuterXml);
> >> >
> >> > // this works although the nav.OuterXml appears wrong
> >> > nav = nav.SelectSingleNode("/order");
> >> > rtn = nav.SelectSingleNode("product[.='software']");
> >> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
> >> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
> >> >
> >> > // this works (same as prev)
> >> > rtn = nav.SelectSingleNode("./product[.='software']");
> >> > Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);
> >> >
> >> > nav = nav.SelectSingleNode("product");
> >> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
> >> >
> >> > // these all fail - WHY?
> >> > try
> >> > {
> >> > rtn = nav.SelectSingleNode("[.='software']");
> >> > }
> >> > catch (XPathException ex)
> >> > {
> >> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> >> > }
> >> > try
> >> > {
> >> > rtn = nav.SelectSingleNode("./[.='software']");
> >> > }
> >> > catch (XPathException ex)
> >> > {
> >> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> >> > }
> >> >
> >> > // yes this works - but I need the node as it does have a value.
> >> > object obj = nav.Evaluate(".='software'");
> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
> >> >
> >> >
> >> > Console.Out.WriteLine("all done");
> >> > }
> >> > }
> >> > }
> >> >
> >> >
> >>
> >>
> >>[/color][/color]
>
>
>
>[/color]
  #6  
Old February 27th, 2006, 08:15 PM
Dimitre Novatchev
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over


"David Thielen" <david@bogus.windward.net> wrote in message
news:DA492C31-ACA4-4280-8A88-78C729376EAA@microsoft.com...[color=blue]
> Hi;
>
> First, thanks for helping on this I really appreciate it.
>
> Ok, I see that the xpath must start with "." to get it to the node and the
> "[...]" then modifies that - makes sense.
>
> But then, shouldn't ".[.='software']" or "./.[.='software']" or[/color]

No, the syntax rules do not allow this:
[color=blue][color=green]
>> [4] Step ::= AxisSpecifier NodeTest Predicate*
>> | AbbreviatedStep[/color][/color]

as we can see, Predicatecan only occur after a NodeTest , not after an
AbbreviatedStep.
[color=blue]
> "./[.='software']" work.[/color]

Again, Predicate cannot be the leftmost symbol in a step
[color=blue]
>
> In the case of ".[.='software']" isn't that saying start with the node "."
> (which exists) and then return all where .='software'?[/color]

This may seem a clear semantics, but the syntax is invalid according to the
XPath 1.0 grammar rules.

As I said, use:

self::node()[.='software']



Cheers,
Dimitre Novatchev
[color=blue]
>
> --
> thanks - dave
> david_at_windward_dot_net
> http://www.windwardreports.com
>
>
>
> "Dimitre Novatchev" wrote:
>[color=green]
>>
>> "David Thielen" <david@bogus.windward.net> wrote in message
>> news:24EA7468-C52A-4765-B556-1EE1DCF81F1B@microsoft.com...[color=darkred]
>> > Hello;
>> >
>> > I assumed it is invalid syntax. My question is why? I don't understand
>> > why
>> > "[.='software']" or some variation of that is invalid.[/color]
>>
>> Read the XPath 1.0 Spec.
>>
>> It says:
>>
>> http://www.w3.org/TR/xpath#predicates
>>
>> "A predicate filters a node-set with respect to an axis to produce a new
>> node-set. For each node in the node-set to be filtered, the PredicateExpr
>> is
>> evaluated with that node as the context node, with the number of nodes in
>> the node-set as the context size, and with the proximity position of the
>> node in the node-set with respect to the axis as the context position; if
>> PredicateExpr evaluates to true for that node, the node is included in
>> the
>> new node-set; otherwise, it is not included."
>>
>>
>>
>> So, a predicate can only apear after some XPath expression and filters
>> it. A
>> predicate, alone, is not a valid XPath expression.
>>
>> This is also made clear if we look at the BNF grammar definition of XPath
>> 1.0. Of all rules only rule [4] and rule [20] contain the nonterminal
>> symbol
>> predicate and it is always not the leading symbol (of the RHS):
>>
>>
>>
>> http://www.w3.org/TR/xpath#section-Location-Steps
>>
>>
>> [4] Step ::= AxisSpecifier NodeTest Predicate*
>> | AbbreviatedStep
>>
>>
>>
>>
>> http://www.w3.org/TR/xpath#node-sets
>>
>>
>>
>> [20] FilterExpr ::= PrimaryExpr
>> | FilterExpr Predicate
>>
>>
>>
>>
>> I hope that this answers completely your question.
>>
>>
>> Cheers,
>> Dimitre Novatchev
>>
>>
>>[color=darkred]
>> >
>> > --
>> > thanks - dave
>> > david_at_windward_dot_net
>> > http://www.windwardreports.com
>> >
>> >
>> >
>> > "Dimitre Novatchev" wrote:
>> >
>> >> > // these all fail - WHY?
>> >>
>> >> because of a common feature -- they all have invalid XPath syntax.
>> >>
>> >> > try
>> >> > {
>> >> > rtn = nav.SelectSingleNode("[.='software']");
>> >> > }
>> >> > catch (XPathException ex)
>> >> > {
>> >> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
>> >> > }
>> >> > try
>> >> > {
>> >> > rtn = nav.SelectSingleNode("./[.='software']");
>> >> > }
>> >> > catch (XPathException ex)
>> >> > {
>> >> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
>> >> > }
>> >> >
>> >> > // yes this works - but I need the node as it does have a value.
>> >> > object obj = nav.Evaluate(".='software'");
>> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >>
>> >>
>> >> Try:
>> >>
>> >> "self::*[.='software']"
>> >>
>> >> or
>> >>
>> >> "string(self::*[.='software'])"
>> >>
>> >> depending on whether you need the node or its string value returned.
>> >>
>> >>
>> >> Cheers,
>> >> Dimitre Novatchev
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> "David Thielen" <david@bogus.windward.net> wrote in message
>> >> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...
>> >> > Hi;
>> >> >
>> >> > I am sure I am missing something here but I cannot figure it out.
>> >> > Below
>> >> > I
>> >> > have a program and I cannot figure out why the xpath selects that
>> >> > throw
>> >> > an
>> >> > exception fail. From what I know they should work.
>> >> >
>> >> > Also the second nav.OuterXml appears to also be wrong to me.
>> >> >
>> >> > Can someone explain to me why this does not work? (This is an
>> >> > example
>> >> > from
>> >> > a
>> >> > program we have where xpath can be entered in two parts so we have
>> >> > to
>> >> > be
>> >> > able
>> >> > to handle this. We can't just always require the fill
>> >> > /order/product[.='software'].)
>> >> >
>> >> > Program below sig.
>> >> >
>> >> > --
>> >> > thanks - dave
>> >> > david_at_windward_dot_net
>> >> > http://www.windwardreports.com
>> >> >
>> >> > Program.cs:
>> >> > using System.Xml;
>> >> > using System.Xml.XPath;
>> >> > using System;
>> >> > using System.IO;
>> >> >
>> >> > namespace XPathSample
>> >> > {
>> >> > class Program
>> >> > {
>> >> > static void Main(string[] args)
>> >> > {
>> >> >
>> >> > string xml =
>> >> > "<order>" +
>> >> > "<product>software</product>" +
>> >> > "<product>software</product>" +
>> >> > "</order>";
>> >> > XPathDocument doc = new XPathDocument(new StringReader(xml));
>> >> >
>> >> > // this works
>> >> > XPathNavigator nav = doc.CreateNavigator();
>> >> > XPathNavigator rtn =
>> >> > nav.SelectSingleNode("/order/product[.='software']");
>> >> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
>> >> > Console.Out.WriteLine("/order/product[.='software'] = " +
>> >> > rtn.OuterXml);
>> >> >
>> >> > // this works although the nav.OuterXml appears wrong
>> >> > nav = nav.SelectSingleNode("/order");
>> >> > rtn = nav.SelectSingleNode("product[.='software']");
>> >> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
>> >> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
>> >> >
>> >> > // this works (same as prev)
>> >> > rtn = nav.SelectSingleNode("./product[.='software']");
>> >> > Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);
>> >> >
>> >> > nav = nav.SelectSingleNode("product");
>> >> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
>> >> >
>> >> > // these all fail - WHY?
>> >> > try
>> >> > {
>> >> > rtn = nav.SelectSingleNode("[.='software']");
>> >> > }
>> >> > catch (XPathException ex)
>> >> > {
>> >> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
>> >> > }
>> >> > try
>> >> > {
>> >> > rtn = nav.SelectSingleNode("./[.='software']");
>> >> > }
>> >> > catch (XPathException ex)
>> >> > {
>> >> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
>> >> > }
>> >> >
>> >> > // yes this works - but I need the node as it does have a value.
>> >> > object obj = nav.Evaluate(".='software'");
>> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >> >
>> >> >
>> >> > Console.Out.WriteLine("all done");
>> >> > }
>> >> > }
>> >> > }
>> >> >
>> >> >
>> >>
>> >>
>> >>[/color]
>>
>>
>>
>>[/color][/color]


  #7  
Old February 27th, 2006, 09:05 PM
David Thielen
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over

Hello;

Is this correct to say:
"/order/software" or "software" in each case is an axis specifier while "."
is an abbreviated step?

I had thought both were a way of specifing a node and therefore were an
axisSpecifier.

Also, any good book(s) or website(s) that explain this, preferably by example?

--
thanks - dave
david_at_windward_dot_net
http://www.windwardreports.com



"Dimitre Novatchev" wrote:
[color=blue]
>
> "David Thielen" <david@bogus.windward.net> wrote in message
> news:DA492C31-ACA4-4280-8A88-78C729376EAA@microsoft.com...[color=green]
> > Hi;
> >
> > First, thanks for helping on this I really appreciate it.
> >
> > Ok, I see that the xpath must start with "." to get it to the node and the
> > "[...]" then modifies that - makes sense.
> >
> > But then, shouldn't ".[.='software']" or "./.[.='software']" or[/color]
>
> No, the syntax rules do not allow this:
>[color=green][color=darkred]
> >> [4] Step ::= AxisSpecifier NodeTest Predicate*
> >> | AbbreviatedStep[/color][/color]
>
> as we can see, Predicatecan only occur after a NodeTest , not after an
> AbbreviatedStep.
>[color=green]
> > "./[.='software']" work.[/color]
>
> Again, Predicate cannot be the leftmost symbol in a step
>[color=green]
> >
> > In the case of ".[.='software']" isn't that saying start with the node "."
> > (which exists) and then return all where .='software'?[/color]
>
> This may seem a clear semantics, but the syntax is invalid according to the
> XPath 1.0 grammar rules.
>
> As I said, use:
>
> self::node()[.='software']
>
>
>
> Cheers,
> Dimitre Novatchev
>[color=green]
> >
> > --
> > thanks - dave
> > david_at_windward_dot_net
> > http://www.windwardreports.com
> >
> >
> >
> > "Dimitre Novatchev" wrote:
> >[color=darkred]
> >>
> >> "David Thielen" <david@bogus.windward.net> wrote in message
> >> news:24EA7468-C52A-4765-B556-1EE1DCF81F1B@microsoft.com...
> >> > Hello;
> >> >
> >> > I assumed it is invalid syntax. My question is why? I don't understand
> >> > why
> >> > "[.='software']" or some variation of that is invalid.
> >>
> >> Read the XPath 1.0 Spec.
> >>
> >> It says:
> >>
> >> http://www.w3.org/TR/xpath#predicates
> >>
> >> "A predicate filters a node-set with respect to an axis to produce a new
> >> node-set. For each node in the node-set to be filtered, the PredicateExpr
> >> is
> >> evaluated with that node as the context node, with the number of nodes in
> >> the node-set as the context size, and with the proximity position of the
> >> node in the node-set with respect to the axis as the context position; if
> >> PredicateExpr evaluates to true for that node, the node is included in
> >> the
> >> new node-set; otherwise, it is not included."
> >>
> >>
> >>
> >> So, a predicate can only apear after some XPath expression and filters
> >> it. A
> >> predicate, alone, is not a valid XPath expression.
> >>
> >> This is also made clear if we look at the BNF grammar definition of XPath
> >> 1.0. Of all rules only rule [4] and rule [20] contain the nonterminal
> >> symbol
> >> predicate and it is always not the leading symbol (of the RHS):
> >>
> >>
> >>
> >> http://www.w3.org/TR/xpath#section-Location-Steps
> >>
> >>
> >> [4] Step ::= AxisSpecifier NodeTest Predicate*
> >> | AbbreviatedStep
> >>
> >>
> >>
> >>
> >> http://www.w3.org/TR/xpath#node-sets
> >>
> >>
> >>
> >> [20] FilterExpr ::= PrimaryExpr
> >> | FilterExpr Predicate
> >>
> >>
> >>
> >>
> >> I hope that this answers completely your question.
> >>
> >>
> >> Cheers,
> >> Dimitre Novatchev
> >>
> >>
> >>
> >> >
> >> > --
> >> > thanks - dave
> >> > david_at_windward_dot_net
> >> > http://www.windwardreports.com
> >> >
> >> >
> >> >
> >> > "Dimitre Novatchev" wrote:
> >> >
> >> >> > // these all fail - WHY?
> >> >>
> >> >> because of a common feature -- they all have invalid XPath syntax.
> >> >>
> >> >> > try
> >> >> > {
> >> >> > rtn = nav.SelectSingleNode("[.='software']");
> >> >> > }
> >> >> > catch (XPathException ex)
> >> >> > {
> >> >> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> >> >> > }
> >> >> > try
> >> >> > {
> >> >> > rtn = nav.SelectSingleNode("./[.='software']");
> >> >> > }
> >> >> > catch (XPathException ex)
> >> >> > {
> >> >> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> >> >> > }
> >> >> >
> >> >> > // yes this works - but I need the node as it does have a value.
> >> >> > object obj = nav.Evaluate(".='software'");
> >> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
> >> >>
> >> >>
> >> >> Try:
> >> >>
> >> >> "self::*[.='software']"
> >> >>
> >> >> or
> >> >>
> >> >> "string(self::*[.='software'])"
> >> >>
> >> >> depending on whether you need the node or its string value returned.
> >> >>
> >> >>
> >> >> Cheers,
> >> >> Dimitre Novatchev
> >> >>
> >> >>
> >> >>
> >> >>
> >> >>
> >> >> "David Thielen" <david@bogus.windward.net> wrote in message
> >> >> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...
> >> >> > Hi;
> >> >> >
> >> >> > I am sure I am missing something here but I cannot figure it out.
> >> >> > Below
> >> >> > I
> >> >> > have a program and I cannot figure out why the xpath selects that
> >> >> > throw
> >> >> > an
> >> >> > exception fail. From what I know they should work.
> >> >> >
> >> >> > Also the second nav.OuterXml appears to also be wrong to me.
> >> >> >
> >> >> > Can someone explain to me why this does not work? (This is an
> >> >> > example
> >> >> > from
> >> >> > a
> >> >> > program we have where xpath can be entered in two parts so we have
> >> >> > to
> >> >> > be
> >> >> > able
> >> >> > to handle this. We can't just always require the fill
> >> >> > /order/product[.='software'].)
> >> >> >
> >> >> > Program below sig.
> >> >> >
> >> >> > --
> >> >> > thanks - dave
> >> >> > david_at_windward_dot_net
> >> >> > http://www.windwardreports.com
> >> >> >
> >> >> > Program.cs:
> >> >> > using System.Xml;
> >> >> > using System.Xml.XPath;
> >> >> > using System;
> >> >> > using System.IO;
> >> >> >
> >> >> > namespace XPathSample
> >> >> > {
> >> >> > class Program
> >> >> > {
> >> >> > static void Main(string[] args)
> >> >> > {
> >> >> >
> >> >> > string xml =
> >> >> > "<order>" +
> >> >> > "<product>software</product>" +
> >> >> > "<product>software</product>" +
> >> >> > "</order>";
> >> >> > XPathDocument doc = new XPathDocument(new StringReader(xml));
> >> >> >
> >> >> > // this works
> >> >> > XPathNavigator nav = doc.CreateNavigator();
> >> >> > XPathNavigator rtn =
> >> >> > nav.SelectSingleNode("/order/product[.='software']");
> >> >> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
> >> >> > Console.Out.WriteLine("/order/product[.='software'] = " +
> >> >> > rtn.OuterXml);
> >> >> >
> >> >> > // this works although the nav.OuterXml appears wrong
> >> >> > nav = nav.SelectSingleNode("/order");
> >> >> > rtn = nav.SelectSingleNode("product[.='software']");
> >> >> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
> >> >> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
> >> >> >
> >> >> > // this works (same as prev)
> >> >> > rtn = nav.SelectSingleNode("./product[.='software']");
> >> >> > Console.Out.WriteLine("./product[.='software'] = " + rtn.OuterXml);
> >> >> >
> >> >> > nav = nav.SelectSingleNode("product");
> >> >> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
> >> >> >
> >> >> > // these all fail - WHY?
> >> >> > try
> >> >> > {
> >> >> > rtn = nav.SelectSingleNode("[.='software']");
> >> >> > }
> >> >> > catch (XPathException ex)
> >> >> > {
> >> >> > Console.Out.WriteLine("[.='software'] exception = " + ex.Message);
> >> >> > }
> >> >> > try
> >> >> > {
> >> >> > rtn = nav.SelectSingleNode("./[.='software']");
> >> >> > }
> >> >> > catch (XPathException ex)
> >> >> > {
> >> >> > Console.Out.WriteLine("./[.='software'] exception = " + ex.Message);
> >> >> > }
> >> >> >
> >> >> > // yes this works - but I need the node as it does have a value.
> >> >> > object obj = nav.Evaluate(".='software'");
> >> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
> >> >> >
> >> >> >
> >> >> > Console.Out.WriteLine("all done");
> >> >> > }
> >> >> > }
> >> >> > }
> >> >> >
> >> >> >
> >> >>
> >> >>
> >> >>
> >>
> >>
> >>
> >>[/color][/color]
>
>
>[/color]
  #8  
Old February 28th, 2006, 07:15 AM
Dimitre Novatchev
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over


"David Thielen" <david@bogus.windward.net> wrote in message
news:2DBE4A4A-E130-4656-BEAD-D8747783FEF9@microsoft.com...[color=blue]
> Hello;
>
> Is this correct to say:
> "/order/software" or "software" in each case is an axis specifier[/color]

No, Axis specifier can be only a predefined (full) name out of 13 axis names
(see below) or an abbreviated axis specifier (just "@").
[color=blue]
> while "."
> is an abbreviated step?
>
> I had thought both were a way of specifing a node and therefore were an
> axisSpecifier.[/color]

No.

The rules from the spec:

[5] AxisSpecifier ::= AxisName '::'
| AbbreviatedAxisSpecifier


[6] AxisName ::= 'ancestor'
| 'ancestor-or-self'
| 'attribute'
| 'child'
| 'descendant'
| 'descendant-or-self'
| 'following'
| 'following-sibling'
| 'namespace'
| 'parent'
| 'preceding'
| 'preceding-sibling'
| 'self'


[13] AbbreviatedAxisSpecifier ::= '@'?



[color=blue]
>
> Also, any good book(s) or website(s) that explain this, preferably by
> example?[/color]

Michael Kay's books on XSLT 1.0, XSLT 2.0 and XPath 2.0
http://www.amazon.com/gp/product/186...lance&n=283155

http://www.amazon.com/gp/product/076...lance&n=283155

http://www.amazon.com/gp/product/076...lance&n=283155


Jeni Tennison's books on the same topics.
http://www.amazon.com/gp/product/159...lance&n=283155

http://www.amazon.com/gp/product/076...lance&n=283155

http://www.amazon.com/gp/product/159...lance&n=283155


Hope this helped.

Cheers,
Dimitre Novatchev.

[color=blue]
>
> --
> thanks - dave
> david_at_windward_dot_net
> http://www.windwardreports.com
>
>
>
> "Dimitre Novatchev" wrote:
>[color=green]
>>
>> "David Thielen" <david@bogus.windward.net> wrote in message
>> news:DA492C31-ACA4-4280-8A88-78C729376EAA@microsoft.com...[color=darkred]
>> > Hi;
>> >
>> > First, thanks for helping on this I really appreciate it.
>> >
>> > Ok, I see that the xpath must start with "." to get it to the node and
>> > the
>> > "[...]" then modifies that - makes sense.
>> >
>> > But then, shouldn't ".[.='software']" or "./.[.='software']" or[/color]
>>
>> No, the syntax rules do not allow this:
>>[color=darkred]
>> >> [4] Step ::= AxisSpecifier NodeTest Predicate*
>> >> | AbbreviatedStep[/color]
>>
>> as we can see, Predicatecan only occur after a NodeTest , not after an
>> AbbreviatedStep.
>>[color=darkred]
>> > "./[.='software']" work.[/color]
>>
>> Again, Predicate cannot be the leftmost symbol in a step
>>[color=darkred]
>> >
>> > In the case of ".[.='software']" isn't that saying start with the node
>> > "."
>> > (which exists) and then return all where .='software'?[/color]
>>
>> This may seem a clear semantics, but the syntax is invalid according to
>> the
>> XPath 1.0 grammar rules.
>>
>> As I said, use:
>>
>> self::node()[.='software']
>>
>>
>>
>> Cheers,
>> Dimitre Novatchev
>>[color=darkred]
>> >
>> > --
>> > thanks - dave
>> > david_at_windward_dot_net
>> > http://www.windwardreports.com
>> >
>> >
>> >
>> > "Dimitre Novatchev" wrote:
>> >
>> >>
>> >> "David Thielen" <david@bogus.windward.net> wrote in message
>> >> news:24EA7468-C52A-4765-B556-1EE1DCF81F1B@microsoft.com...
>> >> > Hello;
>> >> >
>> >> > I assumed it is invalid syntax. My question is why? I don't
>> >> > understand
>> >> > why
>> >> > "[.='software']" or some variation of that is invalid.
>> >>
>> >> Read the XPath 1.0 Spec.
>> >>
>> >> It says:
>> >>
>> >> http://www.w3.org/TR/xpath#predicates
>> >>
>> >> "A predicate filters a node-set with respect to an axis to produce a
>> >> new
>> >> node-set. For each node in the node-set to be filtered, the
>> >> PredicateExpr
>> >> is
>> >> evaluated with that node as the context node, with the number of nodes
>> >> in
>> >> the node-set as the context size, and with the proximity position of
>> >> the
>> >> node in the node-set with respect to the axis as the context position;
>> >> if
>> >> PredicateExpr evaluates to true for that node, the node is included in
>> >> the
>> >> new node-set; otherwise, it is not included."
>> >>
>> >>
>> >>
>> >> So, a predicate can only apear after some XPath expression and filters
>> >> it. A
>> >> predicate, alone, is not a valid XPath expression.
>> >>
>> >> This is also made clear if we look at the BNF grammar definition of
>> >> XPath
>> >> 1.0. Of all rules only rule [4] and rule [20] contain the nonterminal
>> >> symbol
>> >> predicate and it is always not the leading symbol (of the RHS):
>> >>
>> >>
>> >>
>> >> http://www.w3.org/TR/xpath#section-Location-Steps
>> >>
>> >>
>> >> [4] Step ::= AxisSpecifier NodeTest Predicate*
>> >> | AbbreviatedStep
>> >>
>> >>
>> >>
>> >>
>> >> http://www.w3.org/TR/xpath#node-sets
>> >>
>> >>
>> >>
>> >> [20] FilterExpr ::= PrimaryExpr
>> >> | FilterExpr Predicate
>> >>
>> >>
>> >>
>> >>
>> >> I hope that this answers completely your question.
>> >>
>> >>
>> >> Cheers,
>> >> Dimitre Novatchev
>> >>
>> >>
>> >>
>> >> >
>> >> > --
>> >> > thanks - dave
>> >> > david_at_windward_dot_net
>> >> > http://www.windwardreports.com
>> >> >
>> >> >
>> >> >
>> >> > "Dimitre Novatchev" wrote:
>> >> >
>> >> >> > // these all fail - WHY?
>> >> >>
>> >> >> because of a common feature -- they all have invalid XPath syntax.
>> >> >>
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("./[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("./[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> >
>> >> >> > // yes this works - but I need the node as it does have a value.
>> >> >> > object obj = nav.Evaluate(".='software'");
>> >> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >> >>
>> >> >>
>> >> >> Try:
>> >> >>
>> >> >> "self::*[.='software']"
>> >> >>
>> >> >> or
>> >> >>
>> >> >> "string(self::*[.='software'])"
>> >> >>
>> >> >> depending on whether you need the node or its string value
>> >> >> returned.
>> >> >>
>> >> >>
>> >> >> Cheers,
>> >> >> Dimitre Novatchev
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> "David Thielen" <david@bogus.windward.net> wrote in message
>> >> >> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...
>> >> >> > Hi;
>> >> >> >
>> >> >> > I am sure I am missing something here but I cannot figure it out.
>> >> >> > Below
>> >> >> > I
>> >> >> > have a program and I cannot figure out why the xpath selects that
>> >> >> > throw
>> >> >> > an
>> >> >> > exception fail. From what I know they should work.
>> >> >> >
>> >> >> > Also the second nav.OuterXml appears to also be wrong to me.
>> >> >> >
>> >> >> > Can someone explain to me why this does not work? (This is an
>> >> >> > example
>> >> >> > from
>> >> >> > a
>> >> >> > program we have where xpath can be entered in two parts so we
>> >> >> > have
>> >> >> > to
>> >> >> > be
>> >> >> > able
>> >> >> > to handle this. We can't just always require the fill
>> >> >> > /order/product[.='software'].)
>> >> >> >
>> >> >> > Program below sig.
>> >> >> >
>> >> >> > --
>> >> >> > thanks - dave
>> >> >> > david_at_windward_dot_net
>> >> >> > http://www.windwardreports.com
>> >> >> >
>> >> >> > Program.cs:
>> >> >> > using System.Xml;
>> >> >> > using System.Xml.XPath;
>> >> >> > using System;
>> >> >> > using System.IO;
>> >> >> >
>> >> >> > namespace XPathSample
>> >> >> > {
>> >> >> > class Program
>> >> >> > {
>> >> >> > static void Main(string[] args)
>> >> >> > {
>> >> >> >
>> >> >> > string xml =
>> >> >> > "<order>" +
>> >> >> > "<product>software</product>" +
>> >> >> > "<product>software</product>" +
>> >> >> > "</order>";
>> >> >> > XPathDocument doc = new XPathDocument(new StringReader(xml));
>> >> >> >
>> >> >> > // this works
>> >> >> > XPathNavigator nav = doc.CreateNavigator();
>> >> >> > XPathNavigator rtn =
>> >> >> > nav.SelectSingleNode("/order/product[.='software']");
>> >> >> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
>> >> >> > Console.Out.WriteLine("/order/product[.='software'] = " +
>> >> >> > rtn.OuterXml);
>> >> >> >
>> >> >> > // this works although the nav.OuterXml appears wrong
>> >> >> > nav = nav.SelectSingleNode("/order");
>> >> >> > rtn = nav.SelectSingleNode("product[.='software']");
>> >> >> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
>> >> >> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
>> >> >> >
>> >> >> > // this works (same as prev)
>> >> >> > rtn = nav.SelectSingleNode("./product[.='software']");
>> >> >> > Console.Out.WriteLine("./product[.='software'] = " +
>> >> >> > rtn.OuterXml);
>> >> >> >
>> >> >> > nav = nav.SelectSingleNode("product");
>> >> >> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
>> >> >> >
>> >> >> > // these all fail - WHY?
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("./[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("./[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> >
>> >> >> > // yes this works - but I need the node as it does have a value.
>> >> >> > object obj = nav.Evaluate(".='software'");
>> >> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >> >> >
>> >> >> >
>> >> >> > Console.Out.WriteLine("all done");
>> >> >> > }
>> >> >> > }
>> >> >> > }
>> >> >> >
>> >> >> >
>> >> >>
>> >> >>
>> >> >>
>> >>
>> >>
>> >>
>> >>[/color]
>>
>>
>>[/color][/color]


  #9  
Old February 28th, 2006, 07:35 AM
Dimitre Novatchev
Guest
 
Posts: n/a
Default Re: Why does this xpath fail - starting over

> Also, any good book(s) or website(s) that explain this, preferably by[color=blue]
> example?[/color]

I would recommend the XPath Visualizer as a proven tool for playing with
XPath and learning it "the fun way".

Cheers,
Dimitre Novatchev

"David Thielen" <david@bogus.windward.net> wrote in message
news:2DBE4A4A-E130-4656-BEAD-D8747783FEF9@microsoft.com...[color=blue]
> Hello;
>
> Is this correct to say:
> "/order/software" or "software" in each case is an axis specifier while
> "."
> is an abbreviated step?
>
> I had thought both were a way of specifing a node and therefore were an
> axisSpecifier.
>
> Also, any good book(s) or website(s) that explain this, preferably by
> example?
>
> --
> thanks - dave
> david_at_windward_dot_net
> http://www.windwardreports.com
>
>
>
> "Dimitre Novatchev" wrote:
>[color=green]
>>
>> "David Thielen" <david@bogus.windward.net> wrote in message
>> news:DA492C31-ACA4-4280-8A88-78C729376EAA@microsoft.com...[color=darkred]
>> > Hi;
>> >
>> > First, thanks for helping on this I really appreciate it.
>> >
>> > Ok, I see that the xpath must start with "." to get it to the node and
>> > the
>> > "[...]" then modifies that - makes sense.
>> >
>> > But then, shouldn't ".[.='software']" or "./.[.='software']" or[/color]
>>
>> No, the syntax rules do not allow this:
>>[color=darkred]
>> >> [4] Step ::= AxisSpecifier NodeTest Predicate*
>> >> | AbbreviatedStep[/color]
>>
>> as we can see, Predicatecan only occur after a NodeTest , not after an
>> AbbreviatedStep.
>>[color=darkred]
>> > "./[.='software']" work.[/color]
>>
>> Again, Predicate cannot be the leftmost symbol in a step
>>[color=darkred]
>> >
>> > In the case of ".[.='software']" isn't that saying start with the node
>> > "."
>> > (which exists) and then return all where .='software'?[/color]
>>
>> This may seem a clear semantics, but the syntax is invalid according to
>> the
>> XPath 1.0 grammar rules.
>>
>> As I said, use:
>>
>> self::node()[.='software']
>>
>>
>>
>> Cheers,
>> Dimitre Novatchev
>>[color=darkred]
>> >
>> > --
>> > thanks - dave
>> > david_at_windward_dot_net
>> > http://www.windwardreports.com
>> >
>> >
>> >
>> > "Dimitre Novatchev" wrote:
>> >
>> >>
>> >> "David Thielen" <david@bogus.windward.net> wrote in message
>> >> news:24EA7468-C52A-4765-B556-1EE1DCF81F1B@microsoft.com...
>> >> > Hello;
>> >> >
>> >> > I assumed it is invalid syntax. My question is why? I don't
>> >> > understand
>> >> > why
>> >> > "[.='software']" or some variation of that is invalid.
>> >>
>> >> Read the XPath 1.0 Spec.
>> >>
>> >> It says:
>> >>
>> >> http://www.w3.org/TR/xpath#predicates
>> >>
>> >> "A predicate filters a node-set with respect to an axis to produce a
>> >> new
>> >> node-set. For each node in the node-set to be filtered, the
>> >> PredicateExpr
>> >> is
>> >> evaluated with that node as the context node, with the number of nodes
>> >> in
>> >> the node-set as the context size, and with the proximity position of
>> >> the
>> >> node in the node-set with respect to the axis as the context position;
>> >> if
>> >> PredicateExpr evaluates to true for that node, the node is included in
>> >> the
>> >> new node-set; otherwise, it is not included."
>> >>
>> >>
>> >>
>> >> So, a predicate can only apear after some XPath expression and filters
>> >> it. A
>> >> predicate, alone, is not a valid XPath expression.
>> >>
>> >> This is also made clear if we look at the BNF grammar definition of
>> >> XPath
>> >> 1.0. Of all rules only rule [4] and rule [20] contain the nonterminal
>> >> symbol
>> >> predicate and it is always not the leading symbol (of the RHS):
>> >>
>> >>
>> >>
>> >> http://www.w3.org/TR/xpath#section-Location-Steps
>> >>
>> >>
>> >> [4] Step ::= AxisSpecifier NodeTest Predicate*
>> >> | AbbreviatedStep
>> >>
>> >>
>> >>
>> >>
>> >> http://www.w3.org/TR/xpath#node-sets
>> >>
>> >>
>> >>
>> >> [20] FilterExpr ::= PrimaryExpr
>> >> | FilterExpr Predicate
>> >>
>> >>
>> >>
>> >>
>> >> I hope that this answers completely your question.
>> >>
>> >>
>> >> Cheers,
>> >> Dimitre Novatchev
>> >>
>> >>
>> >>
>> >> >
>> >> > --
>> >> > thanks - dave
>> >> > david_at_windward_dot_net
>> >> > http://www.windwardreports.com
>> >> >
>> >> >
>> >> >
>> >> > "Dimitre Novatchev" wrote:
>> >> >
>> >> >> > // these all fail - WHY?
>> >> >>
>> >> >> because of a common feature -- they all have invalid XPath syntax.
>> >> >>
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("./[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("./[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> >
>> >> >> > // yes this works - but I need the node as it does have a value.
>> >> >> > object obj = nav.Evaluate(".='software'");
>> >> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >> >>
>> >> >>
>> >> >> Try:
>> >> >>
>> >> >> "self::*[.='software']"
>> >> >>
>> >> >> or
>> >> >>
>> >> >> "string(self::*[.='software'])"
>> >> >>
>> >> >> depending on whether you need the node or its string value
>> >> >> returned.
>> >> >>
>> >> >>
>> >> >> Cheers,
>> >> >> Dimitre Novatchev
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> "David Thielen" <david@bogus.windward.net> wrote in message
>> >> >> news:741F026C-54CD-4B6D-BDD8-0FA03A7E06D1@microsoft.com...
>> >> >> > Hi;
>> >> >> >
>> >> >> > I am sure I am missing something here but I cannot figure it out.
>> >> >> > Below
>> >> >> > I
>> >> >> > have a program and I cannot figure out why the xpath selects that
>> >> >> > throw
>> >> >> > an
>> >> >> > exception fail. From what I know they should work.
>> >> >> >
>> >> >> > Also the second nav.OuterXml appears to also be wrong to me.
>> >> >> >
>> >> >> > Can someone explain to me why this does not work? (This is an
>> >> >> > example
>> >> >> > from
>> >> >> > a
>> >> >> > program we have where xpath can be entered in two parts so we
>> >> >> > have
>> >> >> > to
>> >> >> > be
>> >> >> > able
>> >> >> > to handle this. We can't just always require the fill
>> >> >> > /order/product[.='software'].)
>> >> >> >
>> >> >> > Program below sig.
>> >> >> >
>> >> >> > --
>> >> >> > thanks - dave
>> >> >> > david_at_windward_dot_net
>> >> >> > http://www.windwardreports.com
>> >> >> >
>> >> >> > Program.cs:
>> >> >> > using System.Xml;
>> >> >> > using System.Xml.XPath;
>> >> >> > using System;
>> >> >> > using System.IO;
>> >> >> >
>> >> >> > namespace XPathSample
>> >> >> > {
>> >> >> > class Program
>> >> >> > {
>> >> >> > static void Main(string[] args)
>> >> >> > {
>> >> >> >
>> >> >> > string xml =
>> >> >> > "<order>" +
>> >> >> > "<product>software</product>" +
>> >> >> > "<product>software</product>" +
>> >> >> > "</order>";
>> >> >> > XPathDocument doc = new XPathDocument(new StringReader(xml));
>> >> >> >
>> >> >> > // this works
>> >> >> > XPathNavigator nav = doc.CreateNavigator();
>> >> >> > XPathNavigator rtn =
>> >> >> > nav.SelectSingleNode("/order/product[.='software']");
>> >> >> > Console.Out.WriteLine("nav(/) = " + nav.OuterXml);
>> >> >> > Console.Out.WriteLine("/order/product[.='software'] = " +
>> >> >> > rtn.OuterXml);
>> >> >> >
>> >> >> > // this works although the nav.OuterXml appears wrong
>> >> >> > nav = nav.SelectSingleNode("/order");
>> >> >> > rtn = nav.SelectSingleNode("product[.='software']");
>> >> >> > Console.Out.WriteLine("nav(/order) = " + nav.OuterXml);
>> >> >> > Console.Out.WriteLine("product[.='software'] = " + rtn.OuterXml);
>> >> >> >
>> >> >> > // this works (same as prev)
>> >> >> > rtn = nav.SelectSingleNode("./product[.='software']");
>> >> >> > Console.Out.WriteLine("./product[.='software'] = " +
>> >> >> > rtn.OuterXml);
>> >> >> >
>> >> >> > nav = nav.SelectSingleNode("product");
>> >> >> > Console.Out.WriteLine("nav(/order/product) = " + nav.OuterXml);
>> >> >> >
>> >> >> > // these all fail - WHY?
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> > try
>> >> >> > {
>> >> >> > rtn = nav.SelectSingleNode("./[.='software']");
>> >> >> > }
>> >> >> > catch (XPathException ex)
>> >> >> > {
>> >> >> > Console.Out.WriteLine("./[.='software'] exception = " +
>> >> >> > ex.Message);
>> >> >> > }
>> >> >> >
>> >> >> > // yes this works - but I need the node as it does have a value.
>> >> >> > object obj = nav.Evaluate(".='software'");
>> >> >> > Console.Out.WriteLine(".='software' evaluate = " + obj);
>> >> >> >
>> >> >> >
>> >> >> > Console.Out.WriteLine("all done");
>> >> >> > }
>> >> >> > }
>> >> >> > }
>> >> >> >
>> >> >> >
>> >> >>
>> >> >>
>> >> >>
>> >>
>> >>
>> >>
>> >>[/color]
>>
>>
>>[/color][/color]