使用Boost JSON解析器的JSON格式错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Boost JSON解析器的JSON格式错误相关的知识,希望对你有一定的参考价值。

我正在尝试使用Boost从名为sessionstore.js的Firefox配置文件夹中读取JSON文件,其中保存当前/最后一个Firefox会话的信息以进行恢复。我编写了一个基于Boost网站XML-based tutorial的程序,只需更换JSON部分的XML部分,如下所示

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>

using boost::property_tree::ptree;
using namespace std;

const string FILENAME = "sessionstore.js";
const string WINDOW_TAG = "windows";

struct session_settings    
{
    void load (const string &FILENAME);
};

void session_settings::load (const string &FILENAME)
{       
    ptree pt;
    read_json (FILENAME, pt);
}

int main()
{
    try
    {
        session_settings Settings;
        Settings.load(FILENAME);
    }
    catch (exception &e)
    {
        cout << "Error: " << e.what() << endl;
    }
    return 0;
}

我正在尝试阅读的JSON文件的内容是

{"windows":[{"tabs":[{"entries":[{"url":"about:home","title":"Mozilla Firefox Start Page","ID":5,"docshellID":11,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA=","docIdentifier":5},{"url":"http://www.google.co.uk/","title":"Google","ID":6,"docshellID":11,"docIdentifier":6,"children":[{"url":"about:blank","ID":7,"docshellID":12,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAd6UctCANBHTk5kAEEug/UAHoizADOUR05MxABBLoP1AAAAAAv////8AAABQAQAAABhodHRwOi8vd3d3Lmdvb2dsZS5jby51ay8AAAAAAAAABAAAAAcAAAAQAAAAB/////8AAAAH/////wAAAAcAAAAQAAAAFwAAAAEAAAAXAAAAAQAAABcAAAABAAAAGAAAAAAAAAAY/////wAAABf/////AAAAF/////8AAAAX/////wEAAAAAAAAAAAABAAA=","docIdentifier":7,"scroll":"0,0"}],"formdata":{"#csi":"1","#hcache":"{"BInSTfL-EtSt8QOl24nrCg":[[69,{}],[14,{}],[60,{}],[81,{"persisted":true}],[42,{}],[43,{}],[83,{}],[95,{"kfe":{"kfeHost":"clients1.google.co.uk","kfeUrlPrefix":"/webpagethumbnail?r=2&f=2&s=300:585&query=&hl=en&gl=uk","maxPrefetchConnections":2,"prefetch":90,"slowConnection":false},"logging":{"csiFraction":0.05,"gen204Fraction":0.05},"msgs":{"loading":"Still loading...","mute":"Mute","noPreview":"Preview not available","sound":"Sound:","soundOff":"off","soundOn":"on","unmute":"Unmute"},"pb":{"desiredHeight":585,"desiredWidth":300,"minHeight":200,"minWidth":300},"time":{"hoverClose":300,"hoverModeTimeout":60,"hoverOpen":125,"loading":100,"longHoverOpen":725,"prefetchOnLoad":3000,"timeout":2500}}],[78,{}],[25,{"m":{"bks":true,"blg":true,"dsc":true,"evn":true,"frm":true,"isch":true,"klg":true,"mbl":true,"nws":true,"plcs":true,"ppl":true,"prc":true,"pts":true,"rcp":true,"shop":true,"vid":true},"t":null}],[64,{}],[105,{}],[22,{"m_errors":{"32":"Sorry, no more results to show.","default":"<font color=red>Error:</font> The server could not complete your request.  Try again in 30 seconds."},"m_tip":"Click for more information"}],[77,{}],[84,{}],[99,{}],[29,{"mcr":5}],[92,{"avgTtfc":2000,"fd":1000,"fl":true,"focus":true,"hpt":250,"kn":true,"mds":"clir,clue,dfn,evn,frim,klg,prc,rl,show,sp,sts,ww,mbl_he,mbl_hs,mbl_re,mbl_rs,mbl_sv,isch","msg":{"dym":"Did you mean:","gs":"Google Search","kntt":"Use the up and down arrow keys to select each result. Press Enter to go to the selection.","sif":"Search instead for","srf":"Showing results for"},"odef":true,"ophe":true,"pq":true,"rpt":41,"tct":" ?","tdur":50}],[24,{}],[38,{}]]}"},"scroll":"0,0"}],"index":2,"hidden":false,"attributes":{"image":"http://www.google.co.uk/favicon.ico"},"storage":{"http://www.google.co.uk":{"web-v":"12_c9c918f0"}}}],"selected":1,"_closedTabs":[],"width":994,"height":688,"screenX":1650,"screenY":24,"sizemode":"normal","title":"Google"}],"selectedWindow":0,"_closedWindows":[{"tabs":[{"entries":[{"url":"about:home","title":"Mozilla Firefox Start Page","ID":0,"docshellID":5,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA="},{"url":"http://www.facebook.com/","title":"Welcome to Facebook - Log In, Sign Up or Learn More","ID":1,"docshellID":5,"docIdentifier":1,"formdata":{"//xhtml:div[@id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select":0,"//xhtml:div[@id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select[2]":0,"#sex":0,"#birthday_month":0,"#birthday_day":0,"#birthday_year":0},"scroll":"0,0"}],"index":2,"hidden":false,"attributes":{"image":"http://www.facebook.com/favicon.ico"}},{"entries":[{"url":"http://twitter.com/","title":"Twitter","ID":3,"docshellID":6,"docIdentifier":3,"children":[{"url":"http://api.twitter.com/receiver.html","ID":4,"docshellID":7,"referrer":"http://twitter.com/","docIdentifier":4,"scroll":"0,0"}],"formdata":{},"scroll":"0,0"}],"index":1,"hidden":false,"attributes":{"image":"http://twitter.com/phoenix/favicon.ico"}}],"selected":2,"_closedTabs":[],"width":994,"height":688,"screenX":1366,"screenY":307,"sizemode":"normal","cookies":[{"host":".facebook.com","value":"J4-69","path":"/","name":"lsd"},{"host":".facebook.com","value":"http%3A%2F%2Fwww.facebook.com%2F","path":"/","name":"reg_fb_gate"},{"host":".facebook.com","value":"http%3A%2F%2Fwww.facebook.com%2F","path":"/","name":"reg_fb_ref"},{"host":".facebook.com","value":"994x624","path":"/","name":"wd"},{"host":".twitter.com","value":"43838368","path":"/","name":"__utmc"},{"host":"twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":"scribe.twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":".twitter.com","value":"BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd","path":"/","name":"_twitter_sess","httponly":true},{"host":".twitter.com","value":"43838368","path":"/","name":"__utmc"},{"host":"twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":"scribe.twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":".twitter.com","value":"BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd","path":"/","name":"_twitter_sess","httponly":true}],"title":"Twitter"}],"session":{"state":"stopped","lastUpdate":1305658398727}}

当我尝试用我的程序加载它时,我收到了错误

Error: sessionstore.js(1): expected value

由于文件只在一行上格式化,这意味着错误可能在文件中的任何位置,因此我通过Javascript beautifier运行它,保留默认选项,并将结果粘贴回原始文件并执行程序。

格式化的JSON是

{
    "windows": [{
        "tabs": [{
            "entries": [{
                "url": "about:home",
                "title": "Mozilla Firefox Start Page",
                "ID": 5,
                "docshellID": 11,
                "owner_b64": "NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA=",
                "docIdentifier": 5
            }, {
                "url": "http://www.google.co.uk/",
                "title": "Google",
                "ID": 6,
                "docshellID": 11,
                "docIdentifier": 6,
                "children": [{
                    "url": "about:blank",
                    "ID": 7,
                    "docshellID": 12,
                    "owner_b64": "NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAd6UctCANBHTk5kAEEug/UAHoizADOUR05MxABBLoP1AAAAAAv////8AAABQAQAAABhodHRwOi8vd3d3Lmdvb2dsZS5jby51ay8AAAAAAAAABAAAAAcAAAAQAAAAB/////8AAAAH/////wAAAAcAAAAQAAAAFwAAAAEAAAAXAAAAAQAAABcAAAABAAAAGAAAAAAAAAAY/////wAAABf/////AAAAF/////8AAAAX/////wEAAAAAAAAAAAABAAA=",
                    "docIdentifier": 7,
                    "scroll": "0,0"
                }],
                "formdata": {
                    "#csi": "1",
                    "#hcache": "{"BInSTfL-EtSt8QOl24nrCg":[[69,{}],[14,{}],[60,{}],[81,{"persisted":true}],[42,{}],[43,{}],[83,{}],[95,{"kfe":{"kfeHost":"clients1.google.co.uk","kfeUrlPrefix":"/webpagethumbnail?r=2&f=2&s=300:585&query=&hl=en&gl=uk","maxPrefetchConnections":2,"prefetch":90,"slowConnection":false},"logging":{"csiFraction":0.05,"gen204Fraction":0.05},"msgs":{"loading":"Still loading...","mute":"Mute","noPreview":"Preview not available","sound":"Sound:","soundOff":"off","soundOn":"on","unmute":"Unmute"},"pb":{"desiredHeight":585,"desiredWidth":300,"minHeight":200,"minWidth":300},"time":{"hoverClose":300,"hoverModeTimeout":60,"hoverOpen":125,"loading":100,"longHoverOpen":725,"prefetchOnLoad":3000,"timeout":2500}}],[78,{}],[25,{"m":{"bks":true,"blg":true,"dsc":true,"evn":true,"frm":true,"isch":true,"klg":true,"mbl":true,"nws":true,"plcs":true,"ppl":true,"prc":true,"pts":true,"rcp":true,"shop":true,"vid":true},"t":null}],[64,{}],[105,{}],[22,{"m_errors":{"32":"Sorry, no more results to show.","default":"<font color=red>Error:</font> The server could not complete your request.  Try again in 30 seconds."},"m_tip":"Click for more information"}],[77,{}],[84,{}],[99,{}],[29,{"mcr":5}],[92,{"avgTtfc":2000,"fd":1000,"fl":true,"focus":true,"hpt":250,"kn":true,"mds":"clir,clue,dfn,evn,frim,klg,prc,rl,show,sp,sts,ww,mbl_he,mbl_hs,mbl_re,mbl_rs,mbl_sv,isch","msg":{"dym":"Did you mean:","gs":"Google Search","kntt":"Use the up and down arrow keys to select each result. Press Enter to go to the selection.","sif":"Search instead for","srf":"Showing results for"},"odef":true,"ophe":true,"pq":true,"rpt":41,"tct":" ?","tdur":50}],[24,{}],[38,{}]]}"
                },
                "scroll": "0,0"
            }],
            "index": 2,
            "hidden": false,
            "attributes": {
                "image": "http://www.google.co.uk/favicon.ico"
            },
            "storage": {
                "http://www.google.co.uk": {
                    "web-v": "12_c9c918f0"
                }
            }
        }],
        "selected": 1,
        "_closedTabs": [],
        "width": 994,
        "height": 688,
        "screenX": 1650,
        "screenY": 24,
        "sizemode": "normal",
        "title": "Google"
    }],
    "selectedWindow": 0,
    "_closedWindows": [{
        "tabs": [{
            "entries": [{
                "url": "about:home",
                "title": "Mozilla Firefox Start Page",
                "ID": 0,
                "docshellID": 5,
                "owner_b64": "NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA="
            }, {
                "url": "http://www.facebook.com/",
                "title": "Welcome to Facebook - Log In, Sign Up or Learn More",
                "ID": 1,
                "docshellID": 5,
                "docIdentifier": 1,
                "formdata": {
                    "//xhtml:div[@id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select": 0,
                    "//xhtml:div[@id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select[2]": 0,
                    "#sex": 0,
                    "#birthday_month": 0,
                    "#birthday_day": 0,
                    "#birthday_year": 0
                },
                "scroll": "0,0"
            }],
            "index": 2,
            "hidden": false,
            "attributes": {
                "image": "http://www.facebook.com/favicon.ico"
            }
        }, {
            "entries": [{
                "url": "http://twitter.com/",
                "title": "Twitter",
                "ID": 3,
                "docshellID": 6,
                "docIdentifier": 3,
                "children": [{
                    "url": "http://api.twitter.com/receiver.html",
                    "ID": 4,
                    "docshellID": 7,
                    "referrer": "http://twitter.com/",
                    "docIdentifier": 4,
                    "scroll": "0,0"
                }],
                "formdata": {},
                "scroll": "0,0"
            }],
            "index": 1,
            "hidden": false,
            "attributes": {
                "image": "http://twitter.com/phoenix/favicon.ico"
            }
        }],
        "selected": 2,
        "_closedTabs": [],
        "width": 994,
        "height": 688,
        "screenX": 1366,
        "screenY": 307,
        "sizemode": "normal",
        "cookies": [{
            "host": ".facebook.com",
            "value": "J4-69",
            "path": "/",
            "name": "lsd"
        }, {
            "host": ".facebook.com",
            "value": "http%3A%2F%2Fwww.facebook.com%2F",
            "path": "/",
            "name": "reg_fb_gate"
        }, {
            "host": ".facebook.com",
            "value": "http%3A%2F%2Fwww.facebook.com%2F",
            "path": "/",
            "name": "reg_fb_ref"
        }, {
            "host": ".facebook.com",
            "value": "994x624",
            "path": "/",
            "name": "wd"
        }, {
            "host": ".twitter.com",
            "value": "43838368",
            "path": "/",
            "name": "__utmc"
        }, {
            "host": "twitter.com",
            "value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
            "path": "/",
            "name": "original_referer"
        }, {
            "host": "scribe.twitter.com",
            "value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
            "path": "/",
            "name": "original_referer"
        }, {
            "host": ".twitter.com",
            "value": "BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd",
            "path": "/",
            "name": "_twitter_sess",
            "httponly": true
        }, {
            "host": ".twitter.com",
            "value": "43838368",
            "path": "/",
            "name": "__utmc"
        }, {
            "host": "twitter.com",
            "value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
            "path": "/",
            "name": "original_referer"
        }, {
            "host": "scribe.twitter.com",
            "value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
            "path": "/",
            "name": "original_referer"
        }, {
            "host": ".twitter.com",
            "value": "BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd",
            "path": "/",
            "name": "_twitter_sess",
            "httponly": true
        }],
        "title": "Twitter"
    }],
    "session": {
        "state": "stopped",
        "lastUpdate": 1305658398727
    }
}

错误

Error: sessionstore.js(179): expected value

现在将故障标识为在倒数第三行,即读取"lastUpdate": 1305658398727的那一行。从what I've read关于JSON格式,这听起来就像这行中缺少一个逗号或括号,但是这个文件已经生成我的Mozilla用于Firefox,我不相信他们会犯错误像那样,所以我认为Boost中的JSON解析器存在问题。任何人都可以确认是否是这种情况,或者我是谁做错了什么?

答案

我认为问题是这个值大于intdouble。我不知道什么数据类型使用BOOST JSON来读取数字。要测试它,只需将数字更改为字符串并再次解析它。在标准中,数字不受限制,但您必须选择一种数据类型来表示它们,并且可能选择了double,显然这个数字还不够。我将看看你是否可以配置用于数字的类型。

编辑:

再看一下实现,使用Spirit实现“数字”规则如下:

number
            =   strict_real_p
                | int_p
                ;

看着精神strict_real_p使用double作为基础类型,而int_p实际上使用int

坏消息是,对于我在代码中看到的,这是不可配置的,因此您必须更改要解释的JSON。

另一答案

在收到Diego Sevilla和c-smile的答案之后,我做了一些谷歌搜索,以弄清楚如何将他们的建议纳入Boost,因为在我的情况下更改JSON文件不是一个选项,我遇到了this ticket on the Boost bug tracker描述我的确切问题。它已经被Boost 1.45修复和发布。但是,我正在使用Ubuntu存储库中的1.42版本,因此需要手动安装较新版本。

另一答案

正如迭戈所说,是因为1305658398727既不适合strict_real_p也不适合int_p生产。

我怀疑您需要其他JSON解析器或自己修改Spirit定义。

要么像这样:

number
            =   strict_real_p
                | int_p
                | int64_p
                ;

或者就像:

number
            =   real_p;

理想情况下,JSON中的日期/时间应由ISO格式的字符串表示。在这种情况下,你不会有这样的问题。我怀疑自1970-01-01以来数据只有几毫秒(javascript Date.valueOf()

以上是关于使用Boost JSON解析器的JSON格式错误的主要内容,如果未能解决你的问题,请参考以下文章

调用 Boost JSON 解析器永远不会返回

C++的Json解析库:jsoncpp和boost(转)

C++使用boost 1.75版本来读写JSON文件

boost::spirit 解析器的编译错误

微信微信小程序 微信开发工具中新创建的json文件,编译报错VM1781:2 pages/module/module.json 文件解析错误 SyntaxError: Unexpected e(代

通过使用 boost 属性树解析 JSON 文件来访问布尔值