Changed XPath behavior for mixed numeric and string keys

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6590 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
the_undefined 2008-03-18 15:30:00 +00:00
parent f6652d1b73
commit 26489efe19
2 changed files with 61 additions and 6 deletions

View file

@ -391,6 +391,7 @@ class Set extends Object {
if (!isset($contexts[0])) {
$contexts = array($data);
}
$tokens = array_slice(explode('/', $path), 1);
do {
$token = array_shift($tokens);
@ -401,7 +402,9 @@ class Set extends Object {
}
$matches = array();
foreach ($contexts as $i => $context) {
$i = 0;
foreach ($contexts as $key => $context) {
$i++;
if (!isset($context['trace'])) {
$context = array('trace' => array(), 'item' => $context, 'key' => null);
}
@ -412,11 +415,24 @@ class Set extends Object {
$matches[] = $context;
continue;
}
if (array_key_exists($token, $context['item']) && (!$conditions || Set::matches($conditions, $context['item'][$token], $i+1))) {
$context['trace'][] = $context['key'];
$context['key'] = $token;
$context['item'] = $context['item'][$token];
$matches[] = $context;
$match = false;
if (array_key_exists($token, $context['item']) && (!$conditions || Set::matches($conditions, $context['item'][$token], $i))) {
$match = array(
'trace' => am($context['trace'], $context['key']),
'key' => $token,
'item' => $context['item'][$token],
);
} else if ($key === $token && (!$conditions || Set::matches($conditions, $context['item'], $i+1))) {
$match = array(
'trace' => am($context['trace'], $key),
'key' => $key,
'item' => $context['item'],
);
}
if ($match) {
$matches[] = $match;
}
}
if (empty($tokens)) {

View file

@ -384,6 +384,45 @@ class SetTest extends UnitTestCase {
$expected = array(2, 3);
$r = Set::extract('/User[id>1][id<=3]/id', $a);
$this->assertEqual($r, $expected);
$single = array(
'User' => array(
'id' => 4,
'name' => 'Neo',
)
);
$tricky = array(
0 => array(
'User' => array(
'id' => 1,
'name' => 'John',
)
),
1 => array(
'User' => array(
'id' => 2,
'name' => 'Bob',
)
),
2 => array(
'User' => array(
'id' => 3,
'name' => 'Tony',
)
),
'User' => array(
'id' => 4,
'name' => 'Neo',
)
);
$expected = array(1, 2, 3, 4);
$r = Set::extract('/User/id', $tricky);
$this->assertEqual($r, $expected);
$expected = array(4);
$r = Set::extract('/User/id', $single);
$this->assertEqual($r, $expected);
}
/**
* undocumented function