Skip to content

Commit 6cd68eb

Browse files
authored
📝 add documentation for JSON Lines (nlohmann#3247)
1 parent 4fc7b3d commit 6cd68eb

File tree

5 files changed

+118
-0
lines changed

5 files changed

+118
-0
lines changed

doc/examples/json_lines.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <sstream>
2+
#include <iostream>
3+
#include <nlohmann/json.hpp>
4+
5+
using json = nlohmann::json;
6+
7+
int main()
8+
{
9+
// JSON Lines (see https://jsonlines.org)
10+
std::stringstream input;
11+
input << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
12+
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
13+
{"name": "May", "wins": []}
14+
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
15+
)";
16+
17+
std::string line;
18+
while (std::getline(input, line))
19+
{
20+
std::cout << json::parse(line) << std::endl;
21+
}
22+
}

doc/examples/json_lines.output

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{"name":"Gilbert","wins":[["straight","7♣"],["one pair","10♥"]]}
2+
{"name":"Alexa","wins":[["two pair","4♠"],["two pair","9♠"]]}
3+
{"name":"May","wins":[]}
4+
{"name":"Deloise","wins":[["three of a kind","5♣"]]}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# JSON Lines
2+
3+
The [JSON Lines](https://jsonlines.org) format is a text format of newline-delimited JSON. In particular:
4+
5+
1. The input must be UTF-8 encoded.
6+
2. Every line must be a valid JSON value.
7+
3. The line separator must be `\n`. As `\r` is silently ignored, `\r\n` is also supported.
8+
4. The final character may be `\n`, but is not required to be one.
9+
10+
!!! example "JSON Text example"
11+
12+
```json
13+
{"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
14+
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
15+
{"name": "May", "wins": []}
16+
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
17+
```
18+
19+
JSON Lines input with more than one value is treated as invalid JSON by the [`parse`](../../api/basic_json/parse.md) or
20+
[`accept`](../../api/basic_json/accept.md) functions. The process it line by line, functions like
21+
[`std::getline`](https://en.cppreference.com/w/cpp/string/basic_string/getline) can be used:
22+
23+
!!! example "Example: Parse JSON Text input line by line"
24+
25+
The example below demonstrates how JSON Lines can be processed.
26+
27+
```cpp
28+
--8<-- "examples/json_lines.cpp"
29+
```
30+
31+
Output:
32+
33+
```json
34+
--8<-- "examples/json_lines.output"
35+
```
36+
37+
!!! warning "Note"
38+
39+
Using [`operator>>`](../../api/basic_json/operator_gtgt.md) like
40+
41+
```cpp
42+
json j;
43+
while (input >> j)
44+
{
45+
std::cout << j << std::endl;
46+
}
47+
```
48+
49+
with a JSON Lines input does not work, because the parser will try to parse one value after the last one.

doc/mkdocs/mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ nav:
6060
- features/object_order.md
6161
- Parsing:
6262
- features/parsing/index.md
63+
- features/parsing/json_lines.md
6364
- features/parsing/parse_exceptions.md
6465
- features/parsing/parser_callbacks.md
6566
- features/parsing/sax_interface.md

test/src/unit-deserialization.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,48 @@ TEST_CASE("deserialization")
10651065
"start_array()"
10661066
}));
10671067
}
1068+
1069+
SECTION("JSON Lines")
1070+
{
1071+
SECTION("Example file")
1072+
{
1073+
std::stringstream ss;
1074+
ss << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
1075+
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
1076+
{"name": "May", "wins": []}
1077+
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
1078+
)";
1079+
1080+
std::string line;
1081+
int object_count = 0;
1082+
while (std::getline(ss, line))
1083+
{
1084+
++object_count;
1085+
CHECK(json::accept(line));
1086+
}
1087+
1088+
CHECK(object_count == 4);
1089+
}
1090+
1091+
SECTION("Example file without trailing newline")
1092+
{
1093+
std::stringstream ss;
1094+
ss << R"({"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
1095+
{"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
1096+
{"name": "May", "wins": []}
1097+
{"name": "Deloise", "wins": [["three of a kind", "5♣"]]})";
1098+
1099+
std::string line;
1100+
int object_count = 0;
1101+
while (std::getline(ss, line))
1102+
{
1103+
++object_count;
1104+
CHECK(json::accept(line));
1105+
}
1106+
1107+
CHECK(object_count == 4);
1108+
}
1109+
}
10681110
}
10691111

10701112
TEST_CASE_TEMPLATE("deserialization of different character types (ASCII)", T,

0 commit comments

Comments
 (0)