当前位置: 首页 > 知识库问答 >
问题:

使用boost/property_tree从json文件中获取值,具有多个元素/数组/子数组C

翟越
2023-03-14
  • 我正在使用VS2013并在C中开发。
  • 我正在使用boop API从标准/合法的json文件中获取值。
  • 我无法提取name4.jsname5.js和name6.js名字
  • 我在stackoverflow/Google上搜索了一遍,没有找到对我正在使用的以下json文件的任何解释。
{
   "background": {
      "scripts": [ "name1.js", "name2.js", "name3.js" ]
   },
      "default_popup": "popup.html",
      "default_title": "__MSG_name__",
   "content_scripts": [ {
      "all_frames": true,
      "js": [ "name4.js", "name5.js", "name6.js" ],
      "match_about_blank": true,
      "matches": [ "http://*/*", "https://*/*" ],
      "run_at": "document_start"
   }, {
      "all_frames": true,
      "js": [ "include.postload.js" ],
      "match_about_blank": true,
      "matches": [ "http://*/*", "https://*/*" ],
      "run_at": "document_end"
   } ]
}

>

  • 正如您在下面的代码中看到的,我能够使用“background.scripts”(boost网站上的示例)提取“name1.js”、“name2.jss”和“name3.js”:

    boost::property_tree::ptree doc;
    boost::property_tree::read_json("C:/Temp\\manifest.json", doc);
    std::vector<string> jsFiles;
    try{
        BOOST_FOREACH(boost::property_tree::ptree::value_type& framePair, doc.get_child("background.scripts")){
            jsFiles.push_back(framePair.second.data());
         }
    }
    catch (boost::exception const &ex){}
    
    • 我想提取其余的js名称,它们是:
      1. 名称4.js
      2. 名称5.js
      3. 名称6.js

    我无法使用下面的代码让它工作:

    BOOST_FOREACH(boost::property_tree::ptree::value_type& framePair2, doc.get_child("content_scripts")){
    jsFiles.push_back(framePair2.second.data());
    

    我得到的是向量字符串中的< code>""。

    我甚至尝试了jsFiles.push_back(framePair2.second.get

    我也尝试过其他方法,但没有成功。

    如果我能得到一个工作代码,我将不胜感激,因为我没有想法。


  • 共有2个答案

    况弘新
    2023-03-14

    如果您想有一个替代方法,您可以使用我在之前的回答中发布的专用解析器(使用C和BOOST读取JSON文件):

    < kbd >在Coliru上直播

    #include <boost/fusion/adapted/std_pair.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <map>
    
    namespace qi = boost::spirit::qi;
    
    std::string const sample = R"(
    {
       "background": {
          "scripts": [ "name1.js", "name2.js", "name3.js" ]
       },
          "default_popup": "popup.html",
          "default_title": "__MSG_name__",
       "content_scripts": [ {
          "all_frames": true,
          "js": [ "name4.js", "name5.js", "name6.js" ],
          "match_about_blank": true,
          "matches": [ "http://*/*", "https://*/*" ],
          "run_at": "document_start"
       }, {
          "all_frames": true,
          "js": [ "include.postload.js" ],
          "match_about_blank": true,
          "matches": [ "http://*/*", "https://*/*" ],
          "run_at": "document_end"
       } ]
    })";
    
    namespace qd_json { // quick and dirty JSON handling
        struct null {};
        using text   = std::string;
        using value  = boost::make_recursive_variant<
                null,
                text,                                      // "string" (roughly!)
                double,                                    // number
                std::map<text, boost::recursive_variant_>, // object
                std::vector<boost::recursive_variant_>,    // array
                bool
            >::type;
        using member = std::pair<text, value>;
        using object = std::map<text, value>;
        using array  = std::vector<value>;
    
        template <typename It, typename Skipper = qi::space_type>
        struct grammar : qi::grammar<It, value(), Skipper>
        {
            grammar() : grammar::base_type(value_) {
                using namespace qi;
    
                text_   = '"' >> raw [*('\\' >> char_ | ~char_('"'))] >> '"';
                null_   = "null" >> attr(null{});
                bool_   = "true" >> attr(true) | "false" >> attr(false);
                value_  = null_ | bool_ | text_ | double_ | object_ | array_;
                member_ = text_ >> ':' >> value_;
                object_ = '{' >> -(member_ % ',') >> '}';
                array_  = '[' >> -(value_  % ',') >> ']';
    
                ////////////////////////////////////////
                // Bonus: properly decoding the string:
                text_   = lexeme [ '"' >> *ch_ >> '"' ];
    
                ch_ = +(
                        ~char_("\"\\")) [ _val += _1 ] |
                           qi::lit("\x5C") >> (               // \ (reverse solidus)
                           qi::lit("\x22") [ _val += '"'  ] | // "    quotation mark  U+0022
                           qi::lit("\x5C") [ _val += '\\' ] | // \    reverse solidus U+005C
                           qi::lit("\x2F") [ _val += '/'  ] | // /    solidus         U+002F
                           qi::lit("\x62") [ _val += '\b' ] | // b    backspace       U+0008
                           qi::lit("\x66") [ _val += '\f' ] | // f    form feed       U+000C
                           qi::lit("\x6E") [ _val += '\n' ] | // n    line feed       U+000A
                           qi::lit("\x72") [ _val += '\r' ] | // r    carriage return U+000D
                           qi::lit("\x74") [ _val += '\t' ] | // t    tab             U+0009
                           qi::lit("\x75")                    // uXXXX                U+XXXX
                                >> _4HEXDIG [ append_utf8(qi::_val, qi::_1) ]
                        );
    
                BOOST_SPIRIT_DEBUG_NODES((text_)(value_)(member_)(object_)(array_)(null_)(bool_))
            }
        private:
            qi::rule<It, text()>            text_, ch_;
            qi::rule<It, null()>            null_;
            qi::rule<It, bool()>            bool_;
            qi::rule<It, value(),  Skipper> value_;
            qi::rule<It, member(), Skipper> member_;
            qi::rule<It, object(), Skipper> object_;
            qi::rule<It, array(),  Skipper> array_;
    
            struct append_utf8_f {
                template <typename...> struct result { typedef void type; };
                template <typename String, typename Codepoint>
                void operator()(String& to, Codepoint codepoint) const {
                    auto out = std::back_inserter(to);
                    boost::utf8_output_iterator<decltype(out)> convert(out);
                    *convert++ = codepoint;
                }
            };
            boost::phoenix::function<append_utf8_f> append_utf8;
            qi::uint_parser<uint32_t, 16, 4, 4> _4HEXDIG;
        };
    
        template <typename Range, typename It = typename boost::range_iterator<Range const>::type>
        value parse(Range const& input) {
            grammar<It> g;
    
            It first(boost::begin(input)), last(boost::end(input));
            value parsed;
            bool ok = qi::phrase_parse(first, last, g, qi::space, parsed);
    
            if (ok && (first == last))
                return parsed;
    
            throw std::runtime_error("Remaining unparsed: '" + std::string(first, last) + "'");
        }
    
        namespace accessors {
            static double          dbl_(qd_json::value const&v) { return boost::get<double>(v); };
            static int             int_(qd_json::value const&v) { return boost::get<double>(v); };
            static std::string     txt_(qd_json::value const&v) { return boost::get<qd_json::text>(v); };
            static qd_json::array  arr_(qd_json::value const&v) { return boost::get<qd_json::array>(v); };
            static qd_json::object obj_(qd_json::value const&v) { return boost::get<qd_json::object>(v); };
        }
    }
    
    using It = std::string::const_iterator;
    
    int main()
    {
        using namespace qd_json::accessors;
    
        auto root = obj_(qd_json::parse(sample));
    
        for(auto& o : arr_(root["content_scripts"]))
            for(auto& f : arr_(obj_(o)["js"]))
                std::cout << txt_(f) << "\n";
    }
    

    印刷品

    name4.js
    name5.js
    name6.js
    include.postload.js
    
    漆雕升
    2023-03-14

    < code >获取

    for(auto& e : pt.get_child("content_scripts"))
        for(auto& r : e.second.get_child("js"))
            std::cout << r.second.get_value<std::string>() << "\n";
    

    应该做

    < kbd >在Coliru上直播

    #include <sstream>
    #include <boost/property_tree/ptree.hpp>
    #include <boost/property_tree/json_parser.hpp>
    #include <iostream>
    
    std::string const sample = R"(
    {
       "background": {
          "scripts": [ "name1.js", "name2.js", "name3.js" ]
       },
          "default_popup": "popup.html",
          "default_title": "__MSG_name__",
       "content_scripts": [ {
          "all_frames": true,
          "js": [ "name4.js", "name5.js", "name6.js" ],
          "match_about_blank": true,
          "matches": [ "http://*/*", "https://*/*" ],
          "run_at": "document_start"
       }, {
          "all_frames": true,
          "js": [ "include.postload.js" ],
          "match_about_blank": true,
          "matches": [ "http://*/*", "https://*/*" ],
          "run_at": "document_end"
       } ]
    })";
    
    using boost::property_tree::ptree;
    namespace j = boost::property_tree::json_parser;
    
    int main() {
        std::istringstream iss(sample);
        ptree pt;
        j::read_json(iss, pt);
    
        for(auto& e : pt.get_child("content_scripts"))
            for(auto& r : e.second.get_child("js"))
                std::cout << r.second.get_value<std::string>() << "\n";
    }
    

    印刷品

    name4.js
    name5.js
    name6.js
    include.postload.js
    
     类似资料:
    • 问题内容: 我正在尝试为多维数组中的特定键选择最大值。我无法“找到”有问题的钥匙… 因此,数组(比我在这里发布的要冗长得多) 我试图在整个数组中找到最大的“ dnum”值,因此在此示例中,$ max =2。我知道max函数允许我执行此操作,但是我不确定如何引用dnum。元素而不将整个对象放入foreach循环中,如果我这样做了,那么max不会成为要使用的函数,对吗? 因此,我无法完全做到这一点:

    • 问题内容: 我如何使用javascript和jquery获取json文件的数组json 我正在尝试下一个代码,它不起作用: 这是一个名为的json文件:questions.json 我想要一个具有以下格式的数组{Biology:{Category:{cell:{question1 ....}}}} 问题答案: 是一个异步函数,因此返回该函数内部的任何内容均无济于事,因为它不在范围内或尚未收到。您可

    • 本文向大家介绍php获取数组元素中头一个数组元素值的实现方法,包括了php获取数组元素中头一个数组元素值的实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php获取数组元素中头一个数组元素值的实现方法。分享给大家供大家参考。具体如下: 在php的内置函数中,获取数组元素值的函数主要有 reset next current prev end 这几个函数. reset (PHP 3,

    • 我使用Unirest从一个endpoint获取所有id,我的数组如下: 现在我想得到所有,其中是0,我使用的是一个逻辑,它将得到,但是,我需要使用Java使用这个条件得到。 有人能帮我解决这个问题吗?

    • 问题内容: 我正在使用Javascript(ES6)/ FaceBook进行反应,并尝试获取大小变化的数组的前3个元素。我想做相当于Linq take(n)。 在我的Jsx文件中,我有以下内容: 然后得到我尝试的前三个项目 这不起作用,因为地图没有设置功能。 你能帮忙吗? 问题答案: 我相信您正在寻找的是:

    • 从 array 中获取 n 个唯一键随机元素。 使用Fisher-Yates算法 对数组进行打乱。 使用 Array.slice() 获取第一个 n 元素。 省略第二个参数,n 从数组中随机取得 1 个元素。 const sampleSize = ([...arr], n = 1) => { let m = arr.length; while (m) { const i = Mat