summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2009-11-03 20:29:10 +0000
committerarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2009-11-03 20:29:10 +0000
commit0092960c9e792c2c89f9f0d8213f855fd4afe634 (patch)
treec3ce5682f2472dfad3fc094b8580ec6ddb14ce2d
parentc0ce7ab70e2ef0e432ab71d35ae14ea11ea6e87f (diff)
XPath: Fixed following and preceding axes
git-svn-id: http://pugixml.googlecode.com/svn/trunk@203 99668b35-9821-0410-8761-19e4c4f06640
-rw-r--r--src/pugixpath.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp
index d29e6c7..e567524 100644
--- a/src/pugixpath.cpp
+++ b/src/pugixpath.cpp
@@ -170,6 +170,13 @@ namespace
return false;
}
+
+ bool node_is_ancestor(xml_node parent, xml_node node)
+ {
+ while (node && node != parent) node = node.parent();
+
+ return parent && node == parent;
+ }
struct document_order_comparator
{
@@ -1605,21 +1612,28 @@ namespace pugi
xml_node cur = n;
- for (;;)
+ // exit from this node so that we don't include descendants
+ while (cur && !cur.next_sibling()) cur = cur.parent();
+ cur = cur.next_sibling();
+
+ if (cur)
{
- if (cur.first_child())
- cur = cur.first_child();
- else if (cur.next_sibling())
- cur = cur.next_sibling();
- else
+ for (;;)
{
- while (cur && !cur.next_sibling()) cur = cur.parent();
- cur = cur.next_sibling();
-
- if (!cur) break;
+ step_push(ns, cur);
+
+ if (cur.first_child())
+ cur = cur.first_child();
+ else if (cur.next_sibling())
+ cur = cur.next_sibling();
+ else
+ {
+ while (cur && !cur.next_sibling()) cur = cur.parent();
+ cur = cur.next_sibling();
+
+ if (!cur) break;
+ }
}
-
- step_push(ns, cur);
}
break;
@@ -1642,7 +1656,7 @@ namespace pugi
cur = cur.last_child();
else
{
- // leaf node
+ // leaf node, can't be ancestor
step_push(ns, cur);
if (cur.previous_sibling())
@@ -1653,8 +1667,8 @@ namespace pugi
{
cur = cur.parent();
if (!cur) break;
-
- step_push(ns, cur);
+
+ if (!node_is_ancestor(cur, n)) step_push(ns, cur);
}
while (!cur.previous_sibling());