-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unclear docs regarding parser_callback_t callbacks #1972
Comments
(I haven't check whether/how this could/should also apply to |
Hi @laomaiweng if you want to learn more about #include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
int main()
{
// a JSON text
auto text = R"(
[
1,
{
"foo": "bar"
}
]
)";
// define parser callback
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
{
if (event == json::parse_event_t::object_start) // ignoring { "foo" : "bar"}
{
return false;
}
else
{
return true;
}
};
// parse (with callback) and serialize JSON
json j_filtered = json::parse(text, cb);
std::cout << std::setw(4) << j_filtered << '\n';
} The output filtered { "foo" : "bar"} successful: [
1
] According to using parser_callback_t =
std::function<bool(int depth, parse_event_t event, BasicJsonType& parsed)>;` you can also use // define parser callback
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
{
// skip object elements with key "Thumbnail"
if (depth > 1)
{
return false;
}
else
{
return true;
}
}; the output is: [
1,
{}
] Hope these are helpful to you. |
Thank you very much for your reply. :) Your example works and mine doesn't because you discard the Using your above code with the following callback: // define parser callback
json::parser_callback_t cb = [](int depth, json::parse_event_t event, json &parsed) {
// skip object containing key "foo"
if (event == json::parse_event_t::object_end && parsed.contains("foo"))
return false;
else
return true;
}; the output is:
Is the |
In my understanding, it can't discard the // if (event == json::parse_event_t::object_start)`
if (event == json::parse_event_t::object_end) //
{
std::cout << "parsed: " << parsed << std::endl;
std::cout << parsed.is_discarded() << std::endl;
return false;
} when it comes to |
This comment has been minimized.
This comment has been minimized.
If at all possible, I'd very much like to know if it's possible to discard an object at |
This comment has been minimized.
This comment has been minimized.
I finally had time to check this issue. Indeed, parsing [
1,
{
"foo": "bar"
}
] gives the follwing callbacks:
And indeed there is a callback of type I can also confirm that parsing the text above with the callback json::parser_callback_t cb = [](int depth, json::parse_event_t event, json & parsed)
{
if (event == json::parse_event_t::object_end)
{
return false;
}
return true;
}; yields this result:
The logics of the callback were never really challenged, and moving it into the SAX parser was quite challenging. I will try to understand your proposed fix and whether it has further implications. |
I'm trying to use the SAX parser with event callbacks to drop certain items when loading a JSON file.
It's not clear to me what event callbacks are/should be called when parsing values inside an array.
Consider this (ignoring all depths > 1):
The docs don't show such an example, but the comments above indicate what I observe. Is it normal that no callback is fired with parse event
value
and depth 1 at the end of the object in the array? This feels a bit awkward because I need to check bothvalue
andobject_end
events at depth 1 inside my array if I want to process all array items. Perhaps the docs could be clearer on this point?Also, the doc indicates that "Discarded values in structured types are skipped". However if during my
object_end
, depth 1 callback I returnfalse
, the array item is merely tagged as discarded (is_discarded() == true
) even after parsing. This also seems to contradict the docs foris_discarded()
: "This function will always be false for JSON values after parsing".This seems to be due to the following check in
json_sax_dom_callback_parser::end_object()
:To match the docs and also drop items from arrays, shouldn't this be:
It tried this and it seems to be working fine, but I didn't check for other impacts this change may have.
FWIW, I'm using json.hpp v3.7.3 on Linux.
Cheers and thanks for the awesome library. :)
The text was updated successfully, but these errors were encountered: