diff --git a/README.md b/README.md index f1b63da..56b1f14 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,8 @@ childpath = '@' operator* operator = (childname | childfilter | recursive) operator* childname = '.' (var_name | '*') -recursive = '..' (var_name | '*') childfilter = '[' ('*' | namelist | indexlist | arrayslice | filterexpr) ']' +recursive = '..' (var_name | childfilter | '*') namelist = var_name (',' (var_name | '\'' .*? '\'' | '"' .*? '"'))* indexlist = index (',' index)* diff --git a/src/Galbar/JsonPath/JsonPath.php b/src/Galbar/JsonPath/JsonPath.php index 96a1cc9..e065dde 100644 --- a/src/Galbar/JsonPath/JsonPath.php +++ b/src/Galbar/JsonPath/JsonPath.php @@ -70,13 +70,21 @@ public static function subtreeGet(&$root, &$partial, $jsonPath, $createInexisten $jsonPath = $match[1]; } } else if (preg_match(Language\Regex::RECURSIVE_SELECTOR, $jsonPath, $match)) { - list($result, $newHasDiverged) = Operation\GetRecursive::apply($partial, $match[1]); - $newSelection = array_merge($newSelection, $result); + $recursivePath = $match[1]; + if ($recursivePath[0] === '[') { + $recursivePath = "$$recursivePath"; + } else { + $recursivePath = "$.$recursivePath"; + } + foreach ($selection as &$partial) { + list($result, $newHasDiverged) = Operation\GetRecursive::apply($root, $partial, $recursivePath); + $newSelection = array_merge($newSelection, $result); + } if (empty($newSelection)) { $selection = false; break; } else { - $jsonPath = $match[2]; + $jsonPath = ""; } } else { throw new \JsonPath\InvalidJsonPathException($jsonPath); diff --git a/src/Galbar/JsonPath/Language/Regex.php b/src/Galbar/JsonPath/Language/Regex.php index ffee223..6e3fcb5 100644 --- a/src/Galbar/JsonPath/Language/Regex.php +++ b/src/Galbar/JsonPath/Language/Regex.php @@ -24,7 +24,7 @@ class Regex // Child regex const CHILD_NAME = '/^\.([\p{L}\_\$][\w\-\$]*|\*)(.*)/u'; - const RECURSIVE_SELECTOR = '/^\.\.([\p{L}\_\$][\w\-\$]*|\*)(.*)/u'; + const RECURSIVE_SELECTOR = '/^\.\.(.+)/u'; // Array expressions const ARRAY_INTERVAL = '/^(?:(-?\d*:-?\d*)|(-?\d*:-?\d*:-?\d*))$/'; diff --git a/src/Galbar/JsonPath/Operation/GetRecursive.php b/src/Galbar/JsonPath/Operation/GetRecursive.php index e30de87..eb4eefa 100644 --- a/src/Galbar/JsonPath/Operation/GetRecursive.php +++ b/src/Galbar/JsonPath/Operation/GetRecursive.php @@ -21,14 +21,19 @@ class GetRecursive { - public static function apply(&$jsonObject, $childName) + public static function apply(&$root, &$partial, $jsonPath) { - list($result, $_) = GetChild::apply($jsonObject, $childName); - if (is_array($jsonObject)) { - foreach ($jsonObject as &$item) { - list($localResult, $_) = GetRecursive::apply($item, $childName); - $result = array_merge($result, $localResult); - } + list($result, $_) = \JsonPath\JsonPath::subtreeGet($root, $partial, $jsonPath); + if ($result === false) { + $result = array(); + } + + if (!is_array($partial)) { + return array($result, true); + } + foreach ($partial as &$item) { + list($localResult, $_) = GetRecursive::apply($root, $item, $jsonPath); + $result = array_merge($result, $localResult); } return array($result, true); } diff --git a/tests/Galbar/JsonPath/JsonObjectIssue64Test.php b/tests/Galbar/JsonPath/JsonObjectIssue64Test.php new file mode 100644 index 0000000..12e85fb --- /dev/null +++ b/tests/Galbar/JsonPath/JsonObjectIssue64Test.php @@ -0,0 +1,70 @@ +json); + $result = $jsonObject->get('$.result[*].data..someField'); + $expected = ["value1", "otherValue1", "value2", "otherValue2", "value3", "otherValue3"]; + $this->assertEquals($expected, $result); + } +} diff --git a/tests/Galbar/JsonPath/JsonObjectTest.php b/tests/Galbar/JsonPath/JsonObjectTest.php index 35a076f..d5b48ab 100644 --- a/tests/Galbar/JsonPath/JsonObjectTest.php +++ b/tests/Galbar/JsonPath/JsonObjectTest.php @@ -428,7 +428,7 @@ public function testGetProvider() array( "red" ), - "$.store..*[?(@..model == null)].color" + "$.store..[?(@..model == null)].color" ), array( array( @@ -732,7 +732,7 @@ public function testSmartGetProvider() array( "red" ), - "$.store..*[?(@..model == null)].color" + "$.store..[?(@..model == null)].color" ), array( array(1, 2, 3),