[erlang-patches] [erlang-bugs] xmerl_xpath doesn't handle "//@*" correctly?
Matthew Dempsky
matthew@REDACTED
Tue Aug 12 08:11:49 CEST 2008
Here is a patch for a handful of XPath bugs I found while trying to
track down the previous issue.
The first four hunks and the seventh hunk fix the handling of
'preceding', 'preceding-sibling', 'following', and 'following-sibling'
to handle when the context nodeset includes a text node. E.g.,
"//text()/preceding::*" or "//b/following::text()" against
"<a>x<b/>x</a>".
The fifth hunk fixes match_attribute to not throw away any accumulated
context nodes just because a non-element node was tested. E.g.,
"//@*" against "<a b='c'>x</a>".
The sixth hunk fixes xmerl_xpath.erl to compile correctly when
-Ddebug=true is given.
(I'm not an xpath guru, so someone should double check that my test
cases aren't bogus. I just used
http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm as
a sanity check.)
--- xmerl_xpath.erl.orig 2008-08-12 00:28:54.000000000 -0500
+++ xmerl_xpath.erl 2008-08-12 00:50:16.000000000 -0500
@@ -525,7 +525,7 @@ match_following_sibling(Tok, N, Acc, Con
case Ps of
[#xmlNode{type = element,
node = #xmlElement{} = PNode}|_] ->
- FollowingSiblings = lists:nthtail(Node#xmlElement.pos,
+ FollowingSiblings = lists:nthtail(get_position(Node),
get_content(PNode)),
lists:foldr(
fun(E, AccX) ->
@@ -553,7 +553,7 @@ match_following(Tok, N, Acc, Context) ->
case Ps of
[#xmlNode{type = element,
node = #xmlElement{} = PNode}|_] ->
- FollowingSiblings = lists:nthtail(Node#xmlElement.pos,
+ FollowingSiblings = lists:nthtail(get_position(Node),
get_content(PNode)),
lists:foldr(
fun(E, AccX) ->
@@ -588,7 +588,7 @@ match_preceding_sibling(Tok, N, Acc, Con
[#xmlNode{type = element,
node = #xmlElement{} = PNode}|_] ->
PrecedingSiblings = lists:sublist(get_content(PNode), 1,
- Node#xmlElement.pos-1),
+ get_position(Node) - 1),
lists:foldr(
fun(E, AccX) ->
ThisN = #xmlNode{type = node_type(E),
@@ -616,7 +616,7 @@ match_preceding(Tok, N, Acc, Context) ->
[#xmlNode{type = element,
node = #xmlElement{} = PNode}|_] ->
PrecedingSiblings = lists:sublist(get_content(PNode), 1,
- Node#xmlElement.pos-1),
+ get_position(Node) - 1),
lists:foldr(
fun(E, AccX) ->
ThisN = #xmlNode{type = node_type(E),
@@ -655,7 +655,7 @@ match_attribute(Tok, N, Acc, Context) ->
end
end, Acc, E#xmlElement.attributes);
_Other ->
- []
+ Acc
end.
node_type(#xmlAttribute{}) -> attribute;
@@ -736,12 +736,12 @@ node_test({name, {_Tag, Prefix, Local}},
case expanded_name(Prefix, Local, Context) of
[] ->
?dbg("node_test(~p, ~p) -> ~p.~n",
- [{Tag, Prefix, Local}, write_node(Name), false]),
+ [{_Tag, Prefix, Local}, write_node(Name), false]),
false;
ExpName ->
Res = (ExpName == {NS#xmlNamespace.default,Name}),
?dbg("node_test(~p, ~p) -> ~p.~n",
- [{Tag, Prefix, Local}, write_node(Name), Res]),
+ [{_Tag, Prefix, Local}, write_node(Name), Res]),
Res
end;
node_test({name, {Tag,_Prefix,_Local}},
@@ -811,4 +811,11 @@ get_content(#xmlElement{content = F} = E
get_content(#xmlDocument{content = C}) when list(C) ->
C;
get_content(#xmlDocument{content = C}) ->
- [C].
+ [C];
+get_content(#xmlText{}) ->
+ [].
+
+get_position(#xmlElement{pos = N}) ->
+ N;
+get_position(#xmlText{pos = N}) ->
+ N.
More information about the erlang-patches
mailing list