15

I have a JSON string where neither the keys nor the values are quoted and I would like to transform it to a correctly formatted JSON.

{basic:{0:{index:0, license:t, nameSID:n, image:"img_left", descriptionSID:t, category:r}}

Is there a Java library that could handle it? I tried Jackson but it does not work.

4 Answers 4

10

You can use JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES with Jackson to allow unquoted field names:

JsonFactory factory = new JsonFactory();
factory.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
JsonParser jp = factory.createJsonParser(new FileInputStream("content.json"));
Sign up to request clarification or add additional context in comments.

4 Comments

I did use that but it will not help for the unquoted values or for unquoted numeric keys (e.g. "0: myValue")
For "licence":"one,two" malformed as licence:one,two how do you suggest choosing the interpretation? I'm guessing you will have to write your own deserializer. Jackson's ObjectMapper and Module functionality might help you.
In my case, I know that I will have only string without , as values. But yes, it looks like I will have to write my own parser.
This answer is pretty old. Is ALLOW_UNQUOTED_FIELD_NAMES available in modern Jackson ObjectMapper?
3

Not sure if you got around to writing you own parser or not, but I did.

https://github.com/ischumacher/rsjp

Here is example usage with your example JSON:

String str = "{basic:{0:{index:0, license:t, nameSID:n, image:\"img_left\", descriptionSID:t, category:r}}";
Map<String, Object> jso = Json.parseJSON(str);
System.out.println(jso);
System.out.println(Json.get(jso, "basic", "0", "image"));

Here is the output:

{
   basic: 
   {
      0: 
      {
         index: 0, 
         license: t, 
         nameSID: n, 
         image: img_left, 
         descriptionSID: t, 
         category: r
      }
   }
}

img_left

Comments

1

I looked into how one might go about customizing Jackson to deal with non-quoted field values (vs. field names). Even though I ended-up writing a hack instead, I'm posting my breadcrumb trail here for others. My code spelunking was done in Jackson 2.7.2.

Jackson Core comes with two concrete implementations of the JsonParser interface:

  • ReaderBasedJsonParser, a parser for character streams (encoding independent)
  • UTF8StreamJsonParser, a parser optimized for UTF-8 byte streams

The code in these two classes is quite redundant, likely out of necessity. Each class has a method which is called by nextToken() when an unexpected character is encountered. ReaderBasedJsonParser's is named _handleOddValue() and UTF8StreamJsonParser's is _handleUnexpectedValue(). Stuff like accepting "NaN" as a numeric value and allowing single-quoted string values happens in here.

My plan (before I came to my senses and realized an awful hack would suffice for my short-term needs) was to subclass one/both of these parsers and override the methods above to handle unquoted string values. Because this method is called when the input stream is in the context of a field value (just after recognizing the colon), it should be possible to read forward until a comma or right curly brace is encountered and count everything read up to that point as a string value. This code is tricky to write as it requires an understanding of Jackson's buffering strategy, the parser's architecture (the current pointer into the current buffer is an instance variable), etc.

To make an ObjectMapper use this custom parser, one must subclass JsonFactory and override the _createParser() method with one which instantiates it. More work might be required to make both the regular and UTF-8 parser work correctly, although it's sufficient to force the use of the regular parser if performance isn't a concern. Then, an instance of this custom JsonFactory may be passed into ObjectMapper's constructor.

Hope this helps someone.

Comments

0

You can use the nuget package unquotedJson, after installed, execute the following F# code, will get more severe quoted json format:

let x = """{
    0:{index:0, license:t, nameSID:n, image:"img:left", descriptionSID:t, category:r}
    }"""
let y = 
    x
    |> JSON.parse
    |> JSON.stringifyNormalJson

the y is:

{"0":{"index":0,"license":"t","nameSID":"n","image":"img:left","descriptionSID":"t","category":"r"}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.