JSON for Modern C++ SAX 解析中的布尔值回调:json_sax::boolean 接口详解与实战

JSON for Modern C++ SAX 解析中的布尔值回调:json_sax::boolean 接口详解与实战
JSON for Modern C SAX 解析中的布尔值回调json_sax::boolean 接口详解与实战【免费下载链接】jsonJSON for Modern C项目地址: https://gitcode.com/GitHub_Trending/js/json本篇技术文章围绕 JSON for Modern Cnlohmann/jsonSAX 解析接口中的布尔值回调函数nlohmann::json_sax::boolean展开。读完本文你将了解该回调在解析流程中的确切触发时机、参数与返回值语义掌握如何通过继承json_sax_t编写自定义事件消费者来拦截、校验或过滤 JSON 中的布尔值并能对照仓库源码确认文本格式与二进制格式BSON、CBOR、MessagePack、UBJSON下的完整调用链。接口定义当读取到一个布尔值时被调用boolean是 SAXSimple API for XML此处被移植为 Simple API for JSON事件接口nlohmann::json_sax的纯虚成员函数之一。官方 API 文档 boolean.md 给出的声明为virtual bool boolean(bool val) 0;其文档语义非常凝练A boolean value was read.读取到了一个布尔值。各要素说明如下要素说明参数val输入从输入中解析出的布尔值即true或false返回值是否继续解析Whether parsing should proceed。返回true表示解析继续返回false表示立即终止版本历史自 3.2.0 版本引入Added in version 3.2.0boolean与其余 12 个虚函数null、number_integer、number_unsigned、number_float、string、binary、key、start_object、end_object、start_array、end_array、parse_error共同构成完整的 SAX 事件集接口总览见 json_sax.md。在仓库源码中该接口的权威定义位于 json_sax.hpptemplatetypename BasicJsonType struct json_sax { // ... /*! brief a boolean value was read param[in] val boolean value return whether parsing should proceed */ virtual bool boolean(bool val) 0;json_sax是一个模板结构体模板参数BasicJsonType是basic_json的某个特化如nlohmann::json同时它还定义了number_integer_t、number_unsigned_t、number_float_t、string_t、binary_t等成员类型别名全部取自BasicJsonType保证事件负载类型与目标 JSON 类型严格一致。需要说明的是在用户层面通常不直接写json_sax而是通过nlohmann::json暴露的类型别名json_sax_t来引用。该别名定义在 json.hppusing json_sax_t json_saxbasic_json;触发机制解析器何时调用 boolean理解boolean何时被调用需要看文本解析器detail::parser的驱动逻辑。在 parser.hpp 中sax_parse_internal根据词法器lexer给出的词法单元类型分发事件case token_type::literal_false: { if (JSON_HEDLEY_UNLIKELY(!sax-boolean(false))) { return false; } break; } // ... case token_type::literal_true: { if (JSON_HEDLEY_UNLIKELY(!sax-boolean(true))) { return false; } break; }由此可以确认三条关键事实文本 JSON 中只有true/false两个字面量会触发该回调分别以常量true、false作为val实参词法层不做任何运行时读取直接传入编译期常量。返回值被解析器严格检查任何一个事件回调返回falsesax_parse_internal立即返回false停止后续扫描这也决定了外层basic_json::sax_parse的静态方法见 json.hpp 中的static bool sax_parse(...)各重载最终会向调用者报告false。回调调用被JSON_HEDLEY_UNLIKELY包裹说明从源码结构看库认为“用户提前终止解析”是低概率分支热路径假设回调总是返回true。仓库内置的三个实现三种典型姿态detail命名空间为json_sax提供了三个内置实现boolean在这三者中的写法恰好代表了三种典型用途均位于 json_sax.hpp1.json_sax_dom_parser构建 DOM 树。这是parse()/sax_parse默认使用的实现其boolean把布尔值交给handle_value挂到引用栈上对应的数组或对象中bool boolean(bool val) { handle_value(val); return true; }json_sax.hpp2.json_sax_dom_callback_parser带回调的 DOM 解析。用于parse(..., callback, ...)系列接口boolean同样经由handle_value走一遍用户回调parse_event_t::value事件允许用户丢弃该布尔值然后无条件返回truejson_sax.hpp。3.json_sax_acceptor只验不存。仅做语法合法性检查、不保留任何数据boolean直接返回truejson_sax.hppbool boolean(bool /*unused*/) { return true; }这三个实现共同印证了boolean返回值的契约返回true意味着“我处理完了请继续”只有返回false才会让解析器刹车。二进制格式下的 boolean 调用链boolean并不只服务文本 JSON。在 binary_reader.hpp 中四种二进制格式的读取器都会调用它BSONbinary_reader.hppBSON 用 1 字节表示布尔读取后以value ! 0折算return get_numberstd::uint8_t(input_format_t::bson, value) sax-boolean(value ! 0);CBORbinary_reader.hpp0xF4/0xF5两个字节分别对应false/truereturn sax-boolean(false); // 0xF4 // ... return sax-boolean(true); // 0xF5MessagePackbinary_reader.hpp与UBJSONbinary_reader.hpp同样按格式各自的布尔编码如 MessagePack 的0xC2/0xC3、UBJSON 的T/F映射为sax-boolean(false)或sax-boolean(true)。这意味着自定义 SAX 消费者如果同时用于from_bson、from_cbor、from_msgpack、from_ubjson等入口也能在统一的boolean回调中捕获到布尔事件而binary事件binary_t的支持自 3.8.0 版本才加入 SAX 接口boolean本身则从 3.2.0 起就存在。完整实战示例用 SAX 消费者观察 boolean 事件官方文档 boolean.md 的示例引用了 sax_parse.cpp。该示例定义了一个事件收集器sax_event_consumer它继承自json::json_sax_t注释中说明继承不是必须的但可以帮助避免遗漏必须实现的函数把所有事件记录为字符串。其中boolean的实现是class sax_event_consumer : public json::json_sax_t { public: std::vectorstd::string events; // ... bool boolean(bool val) override { events.push_back(boolean(val std::string(val ? true : false) )); return true; } // 其余 null / number_* / string / start_object / end_object / // start_array / end_array / key / binary / parse_error 同理 // parse_error 返回 false 以终止解析 }; int main() { // a JSON text auto text R( { Image: { Width: 800, Height: 600, Title: View from 15th Floor, Thumbnail: { Url: http://www.example.com/image/481989943, Height: 125, Width: 100 }, Animated : false, IDs: [116, 943, 234, -38793], DeletionDate: null, Distance: 12.723374634 } }] ); // create a SAX event consumer object sax_event_consumer sec; // parse JSON bool result json::sax_parse(text, sec); // output the recorded events for (auto event : sec.events) { std::cout event \n; } // output the result of sax_parse std::cout \nresult: std::boolalpha result std::endl; }运行输出见 sax_parse.output。与布尔值相关的两行是key(valAnimated) boolean(valfalse)Animated: false这一成员触发了keyboolean(valfalse)两个事件。此外示例末尾故意让输入以]收尾产生语法错误输出显示parse_error(...)被调用且result: false—— 这正演示了回调返回值决定解析去留的整体机制任何事件包括parse_error返回falsesax_parse即返回false。自己动手拦截与校验布尔值由于boolean的参数只有一个bool回调本身不携带位置信息因此典型的实战用法是“状态机式”消费在进入对象前记录当前 key在boolean中做判定。下面示例演示两种能力——过滤只保留布尔值统计与提前终止发现非法布尔配置时停止解析#include iostream #include nlohmann/json.hpp using json nlohmann::json; class boolean_inspector : public json::json_sax_t { public: int booleans_seen 0; bool rejected false; bool key(json::json_sax_t::string_t val) override { current_key val; return true; } bool boolean(bool val) override { booleans_seen 1; std::cout boolean(val std::boolalpha val ) under key: current_key \n; // 业务规则键为 enabled 的值必须是 true否则终止解析 if (current_key enabled !val) { rejected true; return false; // 通知解析器停止 } return true; } bool null() override { return true; } bool number_integer(number_integer_t) override { return true; } bool number_unsigned(number_unsigned_t) override { return true; } bool number_float(number_float_t, const string_t) override { return true; } bool string(string_t) override { return true; } bool binary(json::binary_t) override { return true; } bool start_object(std::size_t) override { return true; } bool end_object() override { return true; } bool start_array(std::size_t) override { return true; } bool end_array() override { return true; } bool parse_error(std::size_t, const std::string, const json::exception) override { return false; } private: json::json_sax_t::string_t current_key; }; int main() { const auto text R({enabled: false, ids: [1, 2]}); boolean_inspector inspector; const bool ok json::sax_parse(text, inspector); std::cout result: std::boolalpha ok , booleans_seen: inspector.booleans_seen \n; }预期输出boolean(valfalse) under key: enabled result: false, booleans_seen: 1可以看到boolean返回false后ids数组中的数字事件不会再触发sax_parse返回false。这与源码中parser.hpp里if (!sax-boolean(...)) return false;的短路逻辑完全一致。使用要点小结契约boolean(bool val)在每个布尔值文本true/false或各二进制格式的布尔编码解析完成后被调用返回true继续、返回false立即终止整个解析并使sax_parse最终返回false。实现要求json_sax全部 13 个成员函数均为纯虚函数自定义消费者必须全部实现可继承json::json_sax_t获得检查提示这是 boolean.md 示例中sax_event_consumer采用完整实现的原因。适用版本boolean自 3.2.0 引入当前仓库版本为 3.12.0见 json_sax.hpp 文件头注释上述行为在该版本下均成立。相关入口文本解析用json::sax_parsesax_parse.md二进制解析用json::from_bson、json::from_cbor、json::from_msgpack、json::from_ubjson带 SAX 参数的重载均可复用同一套boolean回调逻辑。参考实现仓库内置的json_sax_dom_parser默认 DOM 构建、json_sax_dom_callback_parser回调式解析、json_sax_acceptor仅校验三处boolean实现见 json_sax.hpp是编写自定义消费者时最好的对照样本。【免费下载链接】jsonJSON for Modern C项目地址: https://gitcode.com/GitHub_Trending/js/json创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

最新新闻

日新闻

周新闻

月新闻