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

View file

@ -384,6 +384,45 @@ class SetTest extends UnitTestCase {
$expected = array(2, 3); $expected = array(2, 3);
$r = Set::extract('/User[id>1][id<=3]/id', $a); $r = Set::extract('/User[id>1][id<=3]/id', $a);
$this->assertEqual($r, $expected); $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 * undocumented function