[erlang-bugs] [erlang-patches] xmerl_xpath doesn't handle "//@*" correctly?

Bertil Karlsson <>
Tue Aug 12 12:58:00 CEST 2008


Matthew, thanks for this. It will be included in the next patch.

/Bertil

Matthew Dempsky wrote:
> 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.
> _______________________________________________
> erlang-patches mailing list
> 
> http://www.erlang.org/mailman/listinfo/erlang-patches
>
>   




More information about the erlang-bugs mailing list