views:

453

answers:

4

I'm using a JSON example off the web, as seen below.

{
  "menu": "File", 
  "commands": [ 
      {
          "title": "New", 
          "action":"CreateDoc"
      }, 
      {
          "title": "Open", 
          "action": "OpenDoc"
      }, 
      {
          "title": "Close",
          "action": "CloseDoc"
      }
   ] 
}

I've tried loading this in two different parsers, one in C++ and in Python.

Here's Python's traceback.

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/json/__init__.py", line 267, in load
    parse_constant=parse_constant, **kw)
  File "/usr/lib/python2.6/json/__init__.py", line 307, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.6/json/decoder.py", line 319, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.6/json/decoder.py", line 338, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

And here's what jsoncpp reports.

* Line 1, Column 1
  Syntax error: value, object or array expected.

Any clue what I'm doing wrong?

Edit:

Ok, here's some code. For some reason now Python's working. I didn't do anything but go to the store. That must be a Python feature -- goto the store, random errors go away. Those Python devs are geniuses.

But to the point. Here's the C++ code.

bool CFG::CFG_Init( const char* path ) {
    bool r = reader.parse( path, root );
    if( r ) {
        return true;
    } else {
        std::cout << reader.getFormatedErrorMessages() << std::endl;
        return false;
    }
}

I've tried this where 'path' was a std::string as well -- same thing. I'm calling the method like this:

if( !CFG_Init("test.json") ) {
    error("Couldn't load configuration.");
}

And here's the class.

class CFG: virtual Evaluator {
    Json::Reader reader;
    public:
    Json::Value root;
    bool CFG_Init( const char* path);
    Json::Value CFG_Fetch_Raw(Json::Value section, std::string key, Json::Value defval);
    Json::Value CFG_Fetch(Json::Value section, std::string key, Json::Value defval );
};
+1  A: 

It's your parser apparently. I can import correctly the file with simplejson parser in django

>>> from django.utils import simplejson as sj
>>> f=file("x.json")
>>> sj.load(f)
{u'menu': u'File', u'commands': [{u'action': u'CreateDoc', u'title': u'New'}, {u'action': u'OpenDoc', u'title': u'Open'}, {u'action': u'CloseDoc', u'title': u'Close'}]}
>>>
Stefano Borini
Not according to the JSON spec. The keys are strings, and strings are surrounded by double-quotes.
Robert Harvey
That shortcut is only for javascript sources proper json requires the keys be strings--quoted. Check it out http://json.org/
BaroqueBobcat
Therefore I'm wrong ;)
Stefano Borini
+3  A: 

JSLint says the JSON is good:

http://www.jslint.com/

So it must be a problem with your parser, or how it is being called, etc.

Robert Harvey
+1  A: 

That JSON looks perfectly fine. I would check the code that you are using to load it, to make sure that you are loading that file correctly, and using the right encoding for reading the file from disk. Make sure you don't have any problems like trying to read a UTF-16 file as UTF-8, or trying to read CRLF terminated lines in something expecting linefeeds, or reading a file that begins with a BOM with code that doesn't know how to skip it, or anything of the sort. Take a look at the file in a hex editor to check for any invisible characters that might be throwing things off.

Brian Campbell
+1  A: 

Ok, after looking at jsoncpp's code, I realize my error. It wants the document as a string, not a file name.

Scott