[erlang-patches] Another xmerl_xpath patch: 'descendant' axis should return nodes in document order
Matthew Dempsky
matthew@REDACTED
Fri Aug 15 22:10:18 CEST 2008
The XPath spec (implicitly) states that the descendants axis is a
forward axis and therefore it should return nodes in document order:
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.
Document order places elements before their children:
There is an ordering, document order, defined on all the nodes in
the document corresponding to the order in which the first
character of the XML representation of each node occurs in the XML
representation of the document after expansion of general
entities. Thus, the root node will be the first node. Element
nodes occur before their children.
Therefore, "/descendant-or-self::*" applied to
"<a><b><c/><d/></b><e><f/><g/></e></a>" should return a, b, c, d, e,
f, and g in that order. The patch below corrects this.
Also, it corrects ancestor-or-self to be properly recognized as a
reverse axis.
--- xmerl_xpath.erl.patched 2008-08-15 13:43:40.000000000 -0500
+++ xmerl_xpath.erl 2008-08-15 15:07:24.000000000 -0500
@@ -365,6 +365,8 @@
fwd_or_reverse(ancestor, Context) ->
reverse_axis(Context);
+fwd_or_reverse(ancestor_or_self, Context) ->
+ reverse_axis(Context);
fwd_or_reverse(preceding_sibling, Context) ->
reverse_axis(Context);
fwd_or_reverse(preceding, Context) ->
@@ -408,25 +410,25 @@
node = E,
parents = Parents},
NewParents = [N|Parents],
- Acc1 = case node_test(Tok, N, Context) of
- true ->
- [N|Acc];
- false ->
- Acc
- end,
+ Acc1 = match_desc(T, Parents, Tok, Acc, Context),
Acc2 = match_desc(get_content(E), NewParents, Tok, Acc1, Context),
- match_desc(T, Parents, Tok, Acc2, Context);
+ case node_test(Tok, N, Context) of
+ true ->
+ [N|Acc2];
+ false ->
+ Acc2
+ end;
match_desc([E|T], Parents, Tok, Acc, Context) ->
N = #xmlNode{node = E,
type = node_type(E),
parents = Parents},
- Acc1 = case node_test(Tok, N, Context) of
- true ->
- [N|Acc];
- false ->
- Acc
- end,
- match_desc(T, Parents, Tok, Acc1, Context);
+ Acc1 = match_desc(T, Parents, Tok, Acc, Context),
+ case node_test(Tok, N, Context) of
+ true ->
+ [N|Acc1];
+ false ->
+ Acc1
+ end;
match_desc([], _Parents, _Tok, Acc, _Context) ->
Acc.
@@ -435,13 +437,13 @@
%% "The 'descendant-or-self' axis contains the context node and the
%% descendants of the context node."
match_descendant_or_self(Tok, N, Acc, Context) ->
- Acc1 = case node_test(Tok, N, Context) of
- true ->
- [N|Acc];
- false ->
- Acc
- end,
- match_descendant(Tok, N, Acc1, Context).
+ Acc1 = match_descendant(Tok, N, Acc, Context),
+ case node_test(Tok, N, Context) of
+ true ->
+ [N|Acc1];
+ false ->
+ Acc1
+ end.
match_child(Tok, N, Acc, Context) ->
More information about the erlang-patches
mailing list