469,635 Members | 1,931 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,635 developers. It's quick & easy.

bug in msxml? confirmation requested.

Hello,

can anyone confirm the existence of the following effects which I'd consider
being a critical bug in msxml according to w3c's xpath specs?

The Spec says:
"The parent, ancestor, ancestor-or-self, preceding, and preceding-sibling
axes are reverse axes"
http://www.w3.org/TR/2005/CR-xpath20...th-ReverseAxis

However, the implementation only accesses these axes in the right order when
using fixed indices. When using the axis in a predicate or when cycling
through a nodeset instead, the axis happens to be put out in the wrong order
(evaluation order is correct, nodeset population is not).

Consider the following sample document:
<root attrib="testroot">
<first attrib="testfirst">
<second attrib="testsecond">
<third attrib="" />
</second>
<fourth />
</first>
</root>

The following XPath statement shall cycle from the third element to the
root:
"ancestor-or-self::*"
The XPath spec says the result must be: third, second, first and finally
root, when beginning at third element. Instead, the output will be root,
first, second and finally third with msxml.
This is really awful. One might work around it when programmatically
iterating through a node-set, but when using it as a condition in a
straight-forward path the results will not be as intended.
Just consider the following case:
The task is to evaluate the best attribute "attrib" from the third element
upwards, i.e. find an ancestor element that has some value in the attribute.
I'd like to use:
return thirdElement.SelectSingleNode("ancestor-or-self::*[string(@attrib) !=
'']").Value;
but I can't since it will always return "testroot" because this is the first
element in that wrong order.

This sample code can reproduce the bug:

// ---------------------------
// Demo (Console Application):

using System;
using System.Xml;

namespace Trash.XmlTest
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(
@"<root>
<first>
<second>
<third />
</second>
<fourth />
</first>
</root>");
XmlElement element = (XmlElement)
doc.DocumentElement.SelectSingleNode("//third");
foreach (XmlElement e in
element.SelectNodes("ancestor-or-self::*"))
Console.WriteLine(e.LocalName);
Console.ReadLine();
}
}
}

// Output:

root
first
second
third

// Right: third, second, first, root
// -------------------------------------

If this is indeed a bug, does anyone know about a bugfix or where to post a
report to get that fixed? I wonder whether I got something wrong here.

Am I the only one who experiences that behaviour? According to
http://www.google.com/search?q=msxml...tor-or-self%22 I am not.
In that case, why has this not been fixed yet? That's not just a cosmetic
disorder. I found a similar bug report confirmed and apparently fixed (?) by
Microsoft for MSXML Core Services 4.0 (MSXML 3.0).

I am running VS 2005 + .NET 2.0 (MSXML 6.0) on XP Pro SP2 having all
updates, patches, fixes and that stuff. Is it possible that a recent update
revived the old bug?

- Does anyone know whether MS has yet confirmed this one?
- Has anyone else experienced these effects, though this problem may not be
recognized in all cases?
- Which work-arounds are possible?

Thanks in advance,
Matt
Nov 16 '06 #1
19 2410
* Matthias Truxa wrote in microsoft.public.dotnet.xml:
>http://www.w3.org/TR/2005/CR-xpath20...th-ReverseAxis
Note that this is an outdated draft of XPath 2.0, at the moment the only
relevant specification is <http://www.w3.org/TR/xpathunless you are
using a product that claims support for XPath 2.0.
>However, the implementation only accesses these axes in the right order when
using fixed indices. When using the axis in a predicate or when cycling
through a nodeset instead, the axis happens to be put out in the wrong order
(evaluation order is correct, nodeset population is not).
Node-sets do not have an order (they are sets, not sequences) and, more
importantly, what the .SelectNodes method does is up to Microsoft, the
XPath specification does not define the semantics of this method. So no,
this is not a bug.
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Nov 16 '06 #2
Hallo Björn,

thanx for your fast answer and for the spec update, but in there we still
have the same statement:

"An axis is either a forward axis or a reverse axis. An axis that only ever
contains the context node or nodes that are after the context node in
document order is a forward axis. An axis that only ever contains the
context node or nodes that are before the context node in document order is
a reverse axis. Thus, the ancestor, ancestor-or-self, preceding, and
preceding-sibling axes are reverse axes; all other axes are forward axes.
[...]
>>>The proximity position of a member of a node-set with respect to an
axis is defined to be the position of the node in the node-set ordered
in document order if the axis is a forward axis and ordered in reverse
document order if the axis is a reverse axis. <<<< The first position
is 1.
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."
Node-sets do not have an order (they are sets, not sequences) and, more
importantly, what the .SelectNodes method does is up to Microsoft, the
XPath specification does not define the semantics of this method. So no,
this is not a bug.
That wouldn't make sense at all, if each implementation could freely decide.
This would result in chaotic behaviour and one would not be able to evaluate
or at least populate a document correctly. In the text above, it clearly
states that the set is populated in the order of appearance of the nodes in
the document, with respect to the direction order of the axis.

How am I supposed to program a solution for the given case ()??

Also, why has the very same problem considered to BE a bug once?
Meanwhile, I also found a bugfix:
http://support.microsoft.com/default...;EN-US;q291193, but this
from 2002 and for MSXML 3.0:

SYMPTOMS
When you use an XPath reverse axis to specify a nodelist, you find that the
direction of the nodelist is not reversed. The XPath reverse axes include
ancestor, ancestor-or-self, preceding, and preceding-sibling.

STATUS
Microsoft has confirmed that this is a problem in the Microsoft products
that are listed at the beginning of this article.

This bug was corrected in Microsoft XML 3.0 Service Pack 1.

Well - as I'd like to report - it has NOT.
Besten Gruss,
Matt
Nov 16 '06 #3
importantly, what the .SelectNodes method does is up to Microsoft, the
XPath specification does not define the semantics of this method. So no,
this is not a bug.
If it only were the SelectNodes method I wouldn't comply (also this should
be an ordered set too). By the way, a set is a mathematical group (DE:
Menge/Reihe/Gruppe) and therefore rather a sequence with order than some
table or thrown together pieces.

But even in predicates like the following, the order purely reverses:

return thirdElement.SelectSingleNode("ancestor-or-self::*[string(myattrib)
!= '']").Value

spec states that the node test navigation must be third, second, first,
root, not reversed.
Nov 16 '06 #4
Node-sets do not have an order (they are sets, not sequences) and, more
importantly, what the .SelectNodes method does is up to Microsoft, the
XPath specification does not define the semantics of this method. So no,
this is not a bug.
I'm sorry to prove you wrong but this article too states that collections
with xpath, either implicitly or explicitly remain order and can be indexed
as arraylist can. For attributes, you may be right.

"Collections returned by XPath queries preserve document order, hierarchy,
and identity, to the extent that these are defined. That is, a collection of
elements is returned in document order without repeated elements. Because by
definition attributes are unordered, there is no implicit order to
attributes returned for a specific element."
http://msdn.microsoft.com/library/de...7e91009cf3.asp
So my bug report is still open.
Nov 16 '06 #5
* Matthias Truxa wrote in microsoft.public.dotnet.xml:
>"Collections returned by XPath queries preserve document order, hierarchy,
and identity, to the extent that these are defined. That is, a collection of
elements is returned in document order without repeated elements. Because by
definition attributes are unordered, there is no implicit order to
attributes returned for a specific element."
Yes, "in document order" and in

<root attrib="testroot">
<first attrib="testfirst">
<second attrib="testsecond">
<third attrib="" />
</second>
<fourth />
</first>
</root>

the document order of the elements is root, first, second, third.
You said that you get from selectNodes root, first, second, third.
That is precisely the order as documented in the text you cite.
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Nov 16 '06 #6
right, but that does not solve my problem.

I'm going to post a shorter version within the main thread in some minutes..
Nov 16 '06 #7
Hello,

to avoid further misunderstandings, I'm posting a more explained report of
my problem.

Meanwhile I found several sources, stating or not stating that this is a
bug.

MS explains (year 2000) why every selection, even on reversed axes, is in
document order (as long as not being indexed by number), not as the spec
would say, in reversed order to remain XSLT compatibility:
http://groups.google.de/group/micros...ef623d54e54ff2

MS confirms the very same thing as a bug (in 2002):
http://support.microsoft.com/default...;EN-US;q291193 and assures
to have it fixed with MSXML 3+.

There is no further mention of this kind of problem except here
(http://ewbi.blogs.com/develops/2004/...ltxpath_b.html) with .net.

So I'm confused, as are some other people which experienced the same prob
are.
Thing is, that the .net implementation must not behave totally different
from other implementations and especially not different to the spec.
If this order is always reversed (resp. in document order), the reversed
axes would have absolutely no sense except for direct number indexing.

"//third/preceding-sibling::*[1]" will not return the same as
"//third/(preceding-sibling::*)[1]" and also not the same as
but "//third/preceding-sibling::*[anyDynExpr]"
seems to equal "//third/(preceding-sibling::*)[anyDynExpr]"

All I wanted to know is: how am I supposed to code this case, since I cannot
figure another way except evaluating every step programatically on client
side:

<root attrib="testroot">
<first attrib="testfirst">
<second attrib="testsecond">
<third attrib="" />
</second>
<fourth />
</first>
</root>

Task: Get the element having a value in the attribute attrib.
Prefered Solution:
return thirdElement.SelectSingleNode("ancestor-or-self::*[string(@attrib) !=
'']");

Problem:
One would suppose this walks up the hierarchy from third over second over
first to root, but the reverse is the case, it always finds root in the very
first place. So there is no sense of having those axes, except for the
rather dump (staticly known) case you want to select
"ancestor-or-self::[x]", where x is a fixed number or special node position
function. For all other cases the term is taken as an array (instead of
straight-forward processing as xpathnavigator-implementations would let
assume, processed in document order, whether or not it is parenthesised or
not. I would understand, if "(ancestor-or-self::*)[string(@attrib) != '']"
returned elements in the document order and in the case without brackets it
would use the contextual direction.

Whether or not this is a bug I don't have the time left to argument. This
has already taken me hours. If noone is interested in this I won't mind.
I simply wanted to report this inadequacy in case some other folks might
suffer or noone ever recognized this behaviour but counts on the behaviour
like I'd understand it. Still I have to find some preferably efficient
solution to get what I need using the f****** .net implementation of xpath.

If I got something wrong or my english is not understandable this might be
due to the fact its nearly 5AM here in germany meantime.

Can someone from MS please state whether this behaviour is at least known /
is different to other implementations / is logical and no compromise / is a
bug or is being fixed or has already been fixed and just revived or whatever
one could do here?

Thanks in advance,
Matt
Nov 16 '06 #8
Matthias Truxa wrote:
using System;
using System.Xml;

namespace Trash.XmlTest
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(
@"<root>
<first>
<second>
<third />
</second>
<fourth />
</first>
</root>");
XmlElement element = (XmlElement)
doc.DocumentElement.SelectSingleNode("//third");
foreach (XmlElement e in
element.SelectNodes("ancestor-or-self::*"))
Console.WriteLine(e.LocalName);
Console.ReadLine();
}
}
}
This is .NET code and it does not use MSXML at all so I don't understand
why your subject claims there is a bug in MSXML
I am running VS 2005 + .NET 2.0 (MSXML 6.0) on XP Pro SP2 having all
updates, patches, fixes and that stuff.
That code sample above does not use MSXML 6.0, it uses the .NET
XmlDocument class.
--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/
Nov 16 '06 #9

"Matthias Truxa" <us**********************@gmx.netwrote in message
news:eW****************@TK2MSFTNGP03.phx.gbl...
Hello,

can anyone confirm the existence of the following effects which I'd
consider being a critical bug in msxml according to w3c's xpath specs?
As noted by others, your code example is using .NET classes -- not MSXML at
all!

>
The Spec says:
"The parent, ancestor, ancestor-or-self, preceding, and preceding-sibling
axes are reverse axes"
http://www.w3.org/TR/2005/CR-xpath20...th-ReverseAxis

However, the implementation only accesses these axes in the right order
when using fixed indices. When using the axis in a predicate or when
cycling through a nodeset instead, the axis happens to be put out in the
wrong order (evaluation order is correct, nodeset population is not).

Consider the following sample document:
<root attrib="testroot">
<first attrib="testfirst">
<second attrib="testsecond">
<third attrib="" />
</second>
<fourth />
</first>
</root>

The following XPath statement shall cycle from the third element to the
root:
"ancestor-or-self::*"
Not true -- this selects a nodeset -- a nodeset is always in document order.
The XPath spec says the result must be: third, second, first and finally
root, when beginning at third element.
Not true. The XPath spec does not contain such a statement. Please, quote
exactly this statement -- most probably you misunderstand the spec.

Instead, the output will be root, first, second and finally third with
msxml.
Which is correct.
This is really awful. One might work around it when programmatically
iterating through a node-set, but when using it as a condition in a
straight-forward path the results will not be as intended.
Just consider the following case:
The task is to evaluate the best attribute "attrib" from the third element
upwards, i.e. find an ancestor element that has some value in the
attribute.
I'd like to use:
return thirdElement.SelectSingleNode("ancestor-or-self::*[string(@attrib)
!= '']").Value;
but I can't since it will always return "testroot" because this is the
first element in that wrong order.
Once again, the result you get is completely according to the XPath spec.

What is treated differently when evaluating an XPath location step that
contains a reverse axis and one that contains a forward axis is only the
interpretation of the "proximity position".

Thus
following-sibling::*[1]
will select the first in document order following sibling element of the
current node,

while
preceding-sibling::*[1]
will select the first (in reverse-document order) preceding sibling element
of the current node
My general recommendation in all such cases is: please, get a tool like the
XPath Visualizer and play with it to learn the basics of XPath.
Cheers,
Dimitre Novatchev

>
This sample code can reproduce the bug:

// ---------------------------
// Demo (Console Application):

using System;
using System.Xml;

namespace Trash.XmlTest
{
class Program
{
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(
@"<root>
<first>
<second>
<third />
</second>
<fourth />
</first>
</root>");
XmlElement element = (XmlElement)
doc.DocumentElement.SelectSingleNode("//third");
foreach (XmlElement e in
element.SelectNodes("ancestor-or-self::*"))
Console.WriteLine(e.LocalName);
Console.ReadLine();
}
}
}

// Output:

root
first
second
third

// Right: third, second, first, root
// -------------------------------------

If this is indeed a bug, does anyone know about a bugfix or where to post
a report to get that fixed? I wonder whether I got something wrong here.

Am I the only one who experiences that behaviour? According to
http://www.google.com/search?q=msxml...tor-or-self%22 I am not.
In that case, why has this not been fixed yet? That's not just a cosmetic
disorder. I found a similar bug report confirmed and apparently fixed (?)
by Microsoft for MSXML Core Services 4.0 (MSXML 3.0).

I am running VS 2005 + .NET 2.0 (MSXML 6.0) on XP Pro SP2 having all
updates, patches, fixes and that stuff. Is it possible that a recent
update revived the old bug?

- Does anyone know whether MS has yet confirmed this one?
- Has anyone else experienced these effects, though this problem may not
be recognized in all cases?
- Which work-arounds are possible?

Thanks in advance,
Matt


Nov 17 '06 #10
* Dimitre Novatchev wrote in microsoft.public.dotnet.xml:
>Not true -- this selects a nodeset -- a nodeset is always in document order.
A node-set is "an ->unordered<- collection of nodes without duplicates".
--
Björn Höhrmann · mailto:bj****@hoehrmann.de · http://bjoern.hoehrmann.de
Weinh. Str. 22 · Telefon: +49(0)621/4309674 · http://www.bjoernsworld.de
68309 Mannheim · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/
Nov 17 '06 #11

"Bjoern Hoehrmann" <bj****@hoehrmann.dewrote in message
news:im********************************@hive.bjoer n.hoehrmann.de...
>* Dimitre Novatchev wrote in microsoft.public.dotnet.xml:
>>Not true -- this selects a nodeset -- a nodeset is always in document
order.

A node-set is "an ->unordered<- collection of nodes without duplicates".
Exactly.

This is why there is always a widely accepted way of presenting sets -- for
a sets of numbers usually this is in increasing order.

Altjough {1,2,3} is exactly the same set as {2,3,1}, the set is usually
presented in the former way.

For a node-set the accepted order of presenting its items is their document
order.

Cheers,
Dimitre Novatchev.
Nov 17 '06 #12
My general recommendation in all such cases is: please, get a tool like
the XPath Visualizer and play with it to learn the basics of XPath.
Are you serious?
I worked with XPath for years. I neither misunderstood the spec nor am I to
dump to use it.
It may be that I'm not able to clearly state what my problem is.

You all are right that the XPath implementation with .NET might not use
MSXML.
I did not check with reflector whether it is fully written in .NET or
whether it uses the
XML core services. My first thought was it would, since MSXML used to be a
standard system component.
Then maybe MSXML is working correctly and problems only appear in the
smaller area of using XML in .NET, fine.
The following XPath statement shall cycle from the third element to the
root:
"ancestor-or-self::*"
Not true -- this selects a nodeset -- a nodeset is always in document
order.
WTF? Yes, a node-set is in document order, but this statement is NO node-set
intrinsically.
It is a selection in respect to the context and the given axis. Can you tell
me what the sense of a reverse
axis is when it is not reversed?
To Nodesets: A node set is a set of nodes in document order, correct.
However, a axis is not a node-set!
Therefore you cannot say "following-sibling::*" is a node set. Instead, each
result of such a query is one.
For that there is no need to have all elements retrieved in document order,
at least not when the axis clearly
says it it a reverse one.
Thus
following-sibling::*[1]
will select the first in document order following sibling element of the
current node,

while
preceding-sibling::*[1]
will select the first (in reverse-document order) preceding sibling
element of the current node
Thats right and all correct.
Now try the same with:
following-sibling::*[@myattrib != '']
This will select some of the following siblings in document order which has
a value in myattrib.
Now take this one:
preceding-sibling::*[@myattrib != '']
According to any spec and to your sample above, it shall select the first
preceding sibling of the context node, which has a value in myattrib,
meaning it walks up in reversed document order.
Well, what shall I say; it never does. Instead, it walks down in document
order beginning at the first sibling, given me the very next that meets the
condition, which apparently is not what i want nor what one would expect nor
what a reversed axis would make senseful.

Using a statement like "(preceding-sibling::*)[1]" I am able to thread the
whole preceding siblings as a collection, i.e. retrieving the first element
with this statement will return the very first sibling (in document order).
This method does not work with dynamic predicates (although "[1]" is rather
a dynamic since it means "[position() = 1]" condition than a static
indexer), "preceding-sibling::*[@myattrib != '']" exactly behaves as
"(preceding-sibling::*)[@myattrib != '']" does.

Now consider the spec (that doesn't say much, perhaps it was thought to be
clear):
http://www.w3.org/TR/xpath#node-sets
"NOTE: The meaning of a Predicate depends crucially on which axis applies.
For example, preceding::foo[1] returns the first foo element in reverse
document order, because the axis that applies to the [1] predicate is the
preceding axis; by contrast, (preceding::foo)[1] returns the first foo
element in document order, because the axis that applies to the [1]
predicate is the child axis."

That's exactly the case. However, it is not when using a dynamic condition
rather than a static index. That is my point and question - this behaviour
cannot be correct.

Face it:
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."

Thats the problem; there is absolutely no possibility to even use the
reversed axes.
I don't mind where the problem is or whether it's according to the spec or
not, don't be so fussy.

Can anyone solve this task in a single statement (as possible using the
spec) with .NET?

DOC: <root><first a='1'><second a='2'><third a=''
/></second><fourth></first></root>
TASK: Let third be the context node. Find it's or any ancestor's a attribute
to select the first preceding a value, in this case second.a = 2.
SOL: return third.SelectSingleNode("ancestor-or-self::*[@a != '']).Value

This won't function with .NET. I'm just setting up some other
implementations to figure out, whether this always behaves alike. If so,
this restricts the possibilities of XPath for no reason.

I'd be glad to hear of other solutions and different (but fair) opinions.

Matt
Nov 17 '06 #13
Can anyone solve this task in a single statement (as possible using the
spec) with .NET?

DOC: <root><first a='1'><second a='2'><third a=''
/></second><fourth></first></root>
TASK: Let third be the context node. Find it's or any ancestor's a attribute
to select the first preceding a value, in this case second.a = 2.
SOL: return third.SelectSingleNode("ancestor-or-self::*[@a != '']).Value

This won't function with .NET. I'm just setting up some other
implementations to figure out, whether this always behaves alike. If so,
this restricts the possibilities of XPath for no reason.

I'd be glad to hear of other solutions and different (but fair) opinions.
Yep, it is straightforward. Use this XPath expression:

ancestor::*[not(@a='')][1]

or if you do not want to depend on "third" to be the context node:

//third/ancestor::*[not(@a='')][1]

I will intentionally not answer your other questions here -- both
because it is not realistic to teach XPath in a single message and also
because it would be much more helpful to you to find yourself what,
where and why is wrong in your statements.

Cheers,
Dimitre Novatchev
Matthias Truxa wrote:
My general recommendation in all such cases is: please, get a tool like
the XPath Visualizer and play with it to learn the basics of XPath.

Are you serious?
I worked with XPath for years. I neither misunderstood the spec nor am I to
dump to use it.
It may be that I'm not able to clearly state what my problem is.

You all are right that the XPath implementation with .NET might not use
MSXML.
I did not check with reflector whether it is fully written in .NET or
whether it uses the
XML core services. My first thought was it would, since MSXML used to be a
standard system component.
Then maybe MSXML is working correctly and problems only appear in the
smaller area of using XML in .NET, fine.
The following XPath statement shall cycle from the third element to the
root:
"ancestor-or-self::*"
Not true -- this selects a nodeset -- a nodeset is always in document
order.

WTF? Yes, a node-set is in document order, but this statement is NO node-set
intrinsically.
It is a selection in respect to the context and the given axis. Can you tell
me what the sense of a reverse
axis is when it is not reversed?
To Nodesets: A node set is a set of nodes in document order, correct.
However, a axis is not a node-set!
Therefore you cannot say "following-sibling::*" is a node set. Instead, each
result of such a query is one.
For that there is no need to have all elements retrieved in document order,
at least not when the axis clearly
says it it a reverse one.
Thus
following-sibling::*[1]
will select the first in document order following sibling element of the
current node,

while
preceding-sibling::*[1]
will select the first (in reverse-document order) preceding sibling
element of the current node

Thats right and all correct.
Now try the same with:
following-sibling::*[@myattrib != '']
This will select some of the following siblings in document order which has
a value in myattrib.
Now take this one:
preceding-sibling::*[@myattrib != '']
According to any spec and to your sample above, it shall select the first
preceding sibling of the context node, which has a value in myattrib,
meaning it walks up in reversed document order.
Well, what shall I say; it never does. Instead, it walks down in document
order beginning at the first sibling, given me the very next that meets the
condition, which apparently is not what i want nor what one would expect nor
what a reversed axis would make senseful.

Using a statement like "(preceding-sibling::*)[1]" I am able to thread the
whole preceding siblings as a collection, i.e. retrieving the first element
with this statement will return the very first sibling (in document order).
This method does not work with dynamic predicates (although "[1]" is rather
a dynamic since it means "[position() = 1]" condition than a static
indexer), "preceding-sibling::*[@myattrib != '']" exactly behaves as
"(preceding-sibling::*)[@myattrib != '']" does.

Now consider the spec (that doesn't say much, perhaps it was thought to be
clear):
http://www.w3.org/TR/xpath#node-sets
"NOTE: The meaning of a Predicate depends crucially on which axis applies.
For example, preceding::foo[1] returns the first foo element in reverse
document order, because the axis that applies to the [1] predicate is the
preceding axis; by contrast, (preceding::foo)[1] returns the first foo
element in document order, because the axis that applies to the [1]
predicate is the child axis."

That's exactly the case. However, it is not when using a dynamic condition
rather than a static index. That is my point and question - this behaviour
cannot be correct.

Face it:
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."

Thats the problem; there is absolutely no possibility to even use the
reversed axes.
I don't mind where the problem is or whether it's according to the spec or
not, don't be so fussy.

Can anyone solve this task in a single statement (as possible using the
spec) with .NET?

DOC: <root><first a='1'><second a='2'><third a=''
/></second><fourth></first></root>
TASK: Let third be the context node. Find it's or any ancestor's a attribute
to select the first preceding a value, in this case second.a = 2.
SOL: return third.SelectSingleNode("ancestor-or-self::*[@a != '']).Value

This won't function with .NET. I'm just setting up some other
implementations to figure out, whether this always behaves alike. If so,
this restricts the possibilities of XPath for no reason.

I'd be glad to hear of other solutions and different (but fair) opinions.

Matt
Nov 17 '06 #14
dnovatchev,
Yep, it is straightforward. Use this XPath expression:
ancestor::*[not(@a='')][1]
Perfect. A solution I was looking for.
Anyways, I though iterativly looping through the results of
"ancestor::*[not(@a = '')]" would be the same.
Instead, the whole set appears to be populated first, then processed in
document order.
That's not straight-forward then. A xpathnavigator implementation should
provide a more efficient solution.
Just take a look at the SelectSingleNode method. What it does is first
populating all results to check the results count, then returning the first
element.
or if you do not want to depend on "third" to be the context node:
Complexity is not my problem. The sample was intentionally a simple one, for
that people don't have to go into the matter that much. Maybe I should have
made it a bit more complex..
I will intentionally not answer your other questions here -- both
because it is not realistic to teach XPath in a single message and also
because it would be much more helpful to you to find yourself what,
where and why is wrong in your statements.
Sry, that's not helpful at all,
both because it does not explain your recommendations (i.e. you don't say
what you think I got wrong) and also because its ambiguous between either
calling me a complete idiot or stating I should be more careful reading
specs not written in my native language.
So please put it more clearly for me to have a chance to find out what
exactly you intended to say.

Matt
Nov 17 '06 #15
Sorry, don't have time for this, but do read this explanation (and all
other entries on this page) and, I'm sure, you'll understand.

If I recommend one more thing -- it is quite useful when claiming that
a particular XPath engine or XSLT processor has a bug -- to just test
the "repro" with many other processors.

If all processors show the same behaviour, then it is most probably not
a bug.

If only our processor behaves in this way and all other have a
different behaviour, then this reinforces our suspicion of an existing
bug.

The other recommendation to play with a tool like the XPath Visualizer
was also serious (I'm doing this myself quite often). In this way one
checks to see whether his understanding about how an XPath expression
should be evaluated is correct and if not then can start looking for an
explanation. All in all, great experience, fun and timesavings.

Cheers,
Dimitre Novatchev.
Matthias Truxa wrote:
dnovatchev,
Yep, it is straightforward. Use this XPath expression:
ancestor::*[not(@a='')][1]

Perfect. A solution I was looking for.
Anyways, I though iterativly looping through the results of
"ancestor::*[not(@a = '')]" would be the same.
Instead, the whole set appears to be populated first, then processed in
document order.
That's not straight-forward then. A xpathnavigator implementation should
provide a more efficient solution.
Just take a look at the SelectSingleNode method. What it does is first
populating all results to check the results count, then returning the first
element.
or if you do not want to depend on "third" to be the context node:

Complexity is not my problem. The sample was intentionally a simple one, for
that people don't have to go into the matter that much. Maybe I should have
made it a bit more complex..
I will intentionally not answer your other questions here -- both
because it is not realistic to teach XPath in a single message and also
because it would be much more helpful to you to find yourself what,
where and why is wrong in your statements.

Sry, that's not helpful at all,
both because it does not explain your recommendations (i.e. you don't say
what you think I got wrong) and also because its ambiguous between either
calling me a complete idiot or stating I should be more careful reading
specs not written in my native language.
So please put it more clearly for me to have a chance to find out what
exactly you intended to say.

Matt
Nov 18 '06 #16
Somehow the link I pasted didn't get it through... ??

http://dpawson.co.uk/xsl/sect2/N1641.html#d2397e19
Cheers,
Dimitre Novatchev

<dn********@gmail.comwrote in message
news:11**********************@f16g2000cwb.googlegr oups.com...
Sorry, don't have time for this, but do read this explanation (and all
other entries on this page) and, I'm sure, you'll understand.

If I recommend one more thing -- it is quite useful when claiming that
a particular XPath engine or XSLT processor has a bug -- to just test
the "repro" with many other processors.

If all processors show the same behaviour, then it is most probably not
a bug.

If only our processor behaves in this way and all other have a
different behaviour, then this reinforces our suspicion of an existing
bug.

The other recommendation to play with a tool like the XPath Visualizer
was also serious (I'm doing this myself quite often). In this way one
checks to see whether his understanding about how an XPath expression
should be evaluated is correct and if not then can start looking for an
explanation. All in all, great experience, fun and timesavings.

Cheers,
Dimitre Novatchev.
Matthias Truxa wrote:
>dnovatchev,
Yep, it is straightforward. Use this XPath expression:
ancestor::*[not(@a='')][1]

Perfect. A solution I was looking for.
Anyways, I though iterativly looping through the results of
"ancestor::*[not(@a = '')]" would be the same.
Instead, the whole set appears to be populated first, then processed in
document order.
That's not straight-forward then. A xpathnavigator implementation should
provide a more efficient solution.
Just take a look at the SelectSingleNode method. What it does is first
populating all results to check the results count, then returning the
first
element.
or if you do not want to depend on "third" to be the context node:

Complexity is not my problem. The sample was intentionally a simple one,
for
that people don't have to go into the matter that much. Maybe I should
have
made it a bit more complex..
I will intentionally not answer your other questions here -- both
because it is not realistic to teach XPath in a single message and also
because it would be much more helpful to you to find yourself what,
where and why is wrong in your statements.

Sry, that's not helpful at all,
both because it does not explain your recommendations (i.e. you don't say
what you think I got wrong) and also because its ambiguous between either
calling me a complete idiot or stating I should be more careful reading
specs not written in my native language.
So please put it more clearly for me to have a chance to find out what
exactly you intended to say.

Matt

Nov 18 '06 #17
Dimitre,

Thank you for the detailed explanations (link); this really explains the
most things.
Anyways, it does not explain my case "(.
For the simpler predicate [i] everything works fine. I can distinguish which
case
I want explicitly by using brackets to split tight-bound predicates.
But neither spec nor the linked article explain why I can't do so with more
complex filter expressions. Whether or not brackets are used,
the expression will never filter the set in respect to the axis (no
tight-binding possible).
This is - I know know - because of the construction method of the node set.
I thought of a more straight-forward process - my error (although not
against the spec).
You provided the solution of double-filtering (i.e expression[filter][1])
that will do
in the most cases. Nevertheless, it's a pity that this is going to limit the
possibilities of xpath without a reason, especially for performance.
>If I recommend one more thing -- it is quite useful when claiming that
a particular XPath engine or XSLT processor has a bug -- to just test
the "repro" with many other processors.
I'm doing so (mentioned that in some posting earlier).
The GNOME libxml2 behaves exactly as .NET - so 1:0 for you.
I'm still on it using Xalan and others.
Do you have some others in mind? I barely know some I can use instantly.
>The other recommendation to play with a tool like the XPath Visualizer
was also serious (I'm doing this myself quite often). In this way one
Ok. Got it.

Cheers,
Matt
Nov 18 '06 #18
But neither spec nor the linked article explain why I can't do so with
more
complex filter expressions.
It's quite simple. By "complex filter expressions" you understand such, in
which the predicate at the end of the location step is not a positional
predicate.

The proximity position is used only for positional predicates.
Cheers,
Dimitre Novatchev
"Matthias Truxa" <us**********************@gmx.netwrote in message
news:Or**************@TK2MSFTNGP06.phx.gbl...
Dimitre,

Thank you for the detailed explanations (link); this really explains the
most things.
Anyways, it does not explain my case "(.
For the simpler predicate [i] everything works fine. I can distinguish
which case
I want explicitly by using brackets to split tight-bound predicates.
But neither spec nor the linked article explain why I can't do so with
more
complex filter expressions. Whether or not brackets are used,
the expression will never filter the set in respect to the axis (no
tight-binding possible).
This is - I know know - because of the construction method of the node
set.
I thought of a more straight-forward process - my error (although not
against the spec).
You provided the solution of double-filtering (i.e expression[filter][1])
that will do
in the most cases. Nevertheless, it's a pity that this is going to limit
the
possibilities of xpath without a reason, especially for performance.
>>If I recommend one more thing -- it is quite useful when claiming that
a particular XPath engine or XSLT processor has a bug -- to just test
the "repro" with many other processors.

I'm doing so (mentioned that in some posting earlier).
The GNOME libxml2 behaves exactly as .NET - so 1:0 for you.
I'm still on it using Xalan and others.
Do you have some others in mind? I barely know some I can use instantly.
>>The other recommendation to play with a tool like the XPath Visualizer
was also serious (I'm doing this myself quite often). In this way one

Ok. Got it.

Cheers,
Matt


Nov 18 '06 #19
The proximity position is used only for positional predicates.

Right. I know now. I didn't before.
I'm sorry for mistakenly calling it a bug.

Both GNOME's libxml as well as Java's Xalan behave the same way,
they fall back to what is stated in the XSLT spec, at least when testing
it using xsl.

So thank you for taking the trouble.
I may now be able to explain this case to others.

Cheers,
Matt
Nov 18 '06 #20

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by Alfred Taylor | last post: by
3 posts views Thread by Sharon | last post: by
13 posts views Thread by yawnmoth | last post: by
4 posts views Thread by mrjaxon | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.