diff --git a/include/jsoncons_ext/jsonpath/json_location.hpp b/include/jsoncons_ext/jsonpath/json_location.hpp index cdf138206f..5d24f258e7 100644 --- a/include/jsoncons_ext/jsonpath/json_location.hpp +++ b/include/jsoncons_ext/jsonpath/json_location.hpp @@ -463,26 +463,38 @@ namespace jsonpath { }; template - Json* select(Json& root, const basic_json_location& path) + Json* select(Json& root, const basic_path_node& path) { + using path_node_type = basic_path_node; + + std::vector nodes(path.size(), nullptr); + std::size_t len = nodes.size(); + const path_node_type* p = std::addressof(path); + while (p != nullptr) + { + nodes[--len] = p; + p = p->parent(); + } + while (p != nullptr); + Json* current = std::addressof(root); - for (const auto& basic_path_node : path) + for (auto node : nodes) { - if (basic_path_node.node_kind() == path_node_kind::index) + if (node->node_kind() == path_node_kind::index) { - if (current->type() != json_type::array_value || basic_path_node.index() >= current->size()) + if (current->type() != json_type::array_value || node->index() >= current->size()) { return nullptr; } - current = std::addressof(current->at(basic_path_node.index())); + current = std::addressof(current->at(node->index())); } - else if (basic_path_node.node_kind() == path_node_kind::name) + else if (node->node_kind() == path_node_kind::name) { if (current->type() != json_type::object_value) { return nullptr; } - auto it = current->find(basic_path_node.name()); + auto it = current->find(node->name()); if (it == current->object_range().end()) { return nullptr; diff --git a/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp b/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp index 2b79887867..336ca4268c 100644 --- a/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +++ b/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp @@ -184,7 +184,6 @@ namespace detail { using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; - using json_location_type = basic_json_location; using node_receiver_type = typename supertype::node_receiver_type; using selector_type = typename supertype::selector_type; @@ -559,7 +558,6 @@ namespace detail { using pointer = typename supertype::pointer; using path_value_pair_type = typename supertype::path_value_pair_type; using path_node_type = typename supertype::path_node_type; - using json_location_type = typename supertype::path_node_type; using path_generator_type = path_generator; using node_receiver_type = typename supertype::node_receiver_type; @@ -585,8 +583,7 @@ namespace detail { if (ancestor != nullptr) { - json_location_type path(*ancestor); - pointer ptr = jsoncons::jsonpath::select(root,path); + pointer ptr = jsoncons::jsonpath::select(root,*ancestor); if (ptr != nullptr) { this->tail_select(resources, root, *ancestor, *ptr, receiver, options); @@ -611,8 +608,7 @@ namespace detail { if (ancestor != nullptr) { - json_location_type path(*ancestor); - pointer ptr = jsoncons::jsonpath::select(root,path); + pointer ptr = jsoncons::jsonpath::select(root, *ancestor); if (ptr != nullptr) { return this->evaluate_tail(resources, root, *ancestor, *ptr, options, ec);