Skip to content

Commit eb2cb1b

Browse files
committed
jsonpath union with paths works with star
1 parent eca4b75 commit eb2cb1b

File tree

2 files changed

+54
-8
lines changed

2 files changed

+54
-8
lines changed

include/jsoncons_ext/jsonpath/json_query.hpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ enum class path_state
184184
bracketed_single_quoted_name,
185185
bracketed_double_quoted_name,
186186
bracketed_name_or_path,
187+
bracketed_star_or_path,
187188
expr_or_filter_or_slice_or_key,
188189
slice_end_or_end_step,
189190
slice_end,
@@ -216,7 +217,7 @@ struct state_item
216217
{
217218
}
218219

219-
state_item(path_state state)
220+
explicit state_item(path_state state)
220221
: state(state), is_recursive_descent(false), is_union(false)
221222
{
222223
}
@@ -749,6 +750,13 @@ class jsonpath_evaluator : private ser_context
749750
state_stack_.back().state = path_state::dot;
750751
break;
751752
}
753+
case '*':
754+
{
755+
end_all();
756+
transfer_nodes();
757+
state_stack_.back().state = path_state::dot;
758+
break;
759+
}
752760
case ' ':case '\t':
753761
{
754762
selectors_.push_back(make_unique_ptr<name_selector>(buffer));
@@ -1267,8 +1275,8 @@ class jsonpath_evaluator : private ser_context
12671275
++column_;
12681276
break;
12691277
case '*':
1270-
end_all();
12711278
state_stack_.back().state = path_state::comma_or_right_bracket;
1279+
state_stack_.emplace_back(path_state::bracketed_star_or_path, state_stack_.back());
12721280
++p_;
12731281
++column_;
12741282
break;
@@ -1354,6 +1362,37 @@ class jsonpath_evaluator : private ser_context
13541362
return;
13551363
}
13561364
break;
1365+
case path_state::bracketed_star_or_path:
1366+
switch (*p_)
1367+
{
1368+
case ' ':case '\t':
1369+
++p_;
1370+
++column_;
1371+
break;
1372+
case '.':
1373+
buffer.push_back('*');
1374+
buffer.push_back(*p_);
1375+
state_stack_.back().state = path_state::path;
1376+
++p_;
1377+
++column_;
1378+
break;
1379+
case '[':
1380+
buffer.push_back('*');
1381+
buffer.push_back(*p_);
1382+
state_stack_.back().state = path_state::path2;
1383+
++p_;
1384+
++column_;
1385+
break;
1386+
case ',':
1387+
case ']':
1388+
end_all();
1389+
state_stack_.pop_back();
1390+
break;
1391+
default:
1392+
ec = jsonpath_errc::expected_right_bracket;
1393+
return;
1394+
}
1395+
break;
13571396
case path_state::path:
13581397
switch (*p_)
13591398
{

tests/src/jsonpath/jsonpath_tests.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,21 +1573,28 @@ TEST_CASE("jsonpath object union test")
15731573
]
15741574
} )");
15751575

1576-
SECTION("Test 1")
1576+
SECTION("$[firstName,address.city]")
15771577
{
15781578
json expected = json::parse(R"(["John","Nara"])");
15791579
std::string path = "$[firstName,address.city]";
15801580
json result = json_query(root,path);
15811581
CHECK(result == expected);
15821582
}
1583-
SECTION("Test 2")
1583+
SECTION("$[firstName,*.city]")
1584+
{
1585+
json expected = json::parse(R"(["John","Nara"])");
1586+
std::string path = "$[firstName,*.city]";
1587+
json result = json_query(root,path);
1588+
CHECK(result == expected);
1589+
}
1590+
SECTION("$[firstName,address[city]]")
15841591
{
15851592
json expected = json::parse(R"(["John","Nara"])");
15861593
std::string path = "$[firstName,address[city]]";
15871594
json result = json_query(root,path);
15881595
CHECK(result == expected);
15891596
}
1590-
SECTION("Test 3")
1597+
SECTION("$[firstName,address['city']]")
15911598
{
15921599
json expected = json::parse(R"(["John","Nara"])");
15931600
std::string path = "$[firstName,address['city']]";
@@ -1608,21 +1615,21 @@ TEST_CASE("jsonpath object union test")
16081615
json result = json_query(root,path);
16091616
CHECK(result == expected);
16101617
}
1611-
SECTION("Test 4")
1618+
SECTION(R"($[firstName,address["city"]])")
16121619
{
16131620
json expected = json::parse(R"(["John","Nara"])");
16141621
std::string path = R"($[firstName,address["city"]])";
16151622
json result = json_query(root,path);
16161623
CHECK(result == expected);
16171624
}
1618-
SECTION("Test 5")
1625+
SECTION(R"($['firstName','address'["city"]])")
16191626
{
16201627
json expected = json::parse(R"(["John","Nara"])");
16211628
std::string path = R"($['firstName','address'["city"]])";
16221629
json result = json_query(root,path);
16231630
CHECK(result == expected);
16241631
}
1625-
SECTION("Test 6")
1632+
SECTION(R"($["firstName","address"["city"]])")
16261633
{
16271634
json expected = json::parse(R"(["John","Nara"])");
16281635
std::string path = R"($["firstName","address"["city"]])";

0 commit comments

Comments
 (0)