XPath: Fixed following and preceding axes

git-svn-id: http://pugixml.googlecode.com/svn/trunk@203 99668b35-9821-0410-8761-19e4c4f06640
This commit is contained in:
arseny.kapoulkine 2009-11-03 20:29:10 +00:00
parent c0ce7ab70e
commit 0092960c9e

View File

@ -171,6 +171,13 @@ namespace
return false; 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 struct document_order_comparator
{ {
bool operator()(const xpath_node& lhs, const xpath_node& rhs) const bool operator()(const xpath_node& lhs, const xpath_node& rhs) const
@ -1605,21 +1612,28 @@ namespace pugi
xml_node cur = n; 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()) for (;;)
cur = cur.first_child();
else if (cur.next_sibling())
cur = cur.next_sibling();
else
{ {
while (cur && !cur.next_sibling()) cur = cur.parent(); step_push(ns, cur);
cur = cur.next_sibling();
if (!cur) break; 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; break;
@ -1642,7 +1656,7 @@ namespace pugi
cur = cur.last_child(); cur = cur.last_child();
else else
{ {
// leaf node // leaf node, can't be ancestor
step_push(ns, cur); step_push(ns, cur);
if (cur.previous_sibling()) if (cur.previous_sibling())
@ -1654,7 +1668,7 @@ namespace pugi
cur = cur.parent(); cur = cur.parent();
if (!cur) break; if (!cur) break;
step_push(ns, cur); if (!node_is_ancestor(cur, n)) step_push(ns, cur);
} }
while (!cur.previous_sibling()); while (!cur.previous_sibling());