Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.

Closed 9 years ago .

I am running into a weird problem where if I try to convert a JSON string (which is laid out something like this :- )

"a" : "b", "c" : ["" , ""]

JSON::XS->new->decode works fine in these cases. But if I have something like this to be decoded ,

"women": "" "men" : ""

I think these quotes are the culprit out here . It keeps throwing error that there should be a closing quote. This JSON comes from JSON.stringify in JS so I cannot quite make it work. I have seen JSON::decode_json working for some people out here but I am specifically looking to get it all working with JSON::XS. Worst case , I'll import JSON from cpan.

Any suggestions ?

Edit: I investigated this a lil bit. This is the JSON I am trying to convert into a perl HASH

"womens": [ "/sports/size-charts/a/B00EJ493TW/womens.html", "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/womens.html", "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/womens.html", "/sports/size-charts/b/Yvette/womens.html", "/sports/size-charts/c/SPORTING_GOODS/womens.html" "mens": [ "/sports/size-charts/a/B00EJ493TW/mens.html", "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/mens.html", "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/mens.html", "/sports/size-charts/b/Yvette/mens.html", "/sports/size-charts/c/SPORTING_GOODS/mens.html" "kids": [ "/sports/size-charts/a/B00EJ493TW/kids.html", "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/kids.html", "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/kids.html", "/sports/size-charts/b/Yvette/kids.html", "/sports/size-charts/c/SPORTING_GOODS/kids.html"

When I send this JSON back , it gets HTML Encoded (Quotes replaced by &34;) and that is where Perl croaks with this error :-

     '"' expected, at character offset 1 [""womens":[&#..."]

Any help is greatly appreciated

Sorry I mistyped it in a hurry. Of course there is a comma and everything.I'll update the exact JSON – aasthetic Jul 8, 2014 at 16:44

The JSON you have now posted is valid, which can be ascertained by the fact that JSON::XS does not throw an error (contrary to what you said).

use strict;
use warnings;
use Data::Dumper qw( Dumper );
use JSON::XS     qw( decode_json );
my $json = <<'__EOI__';
  "womens": [
    "/sports/size-charts/a/B00EJ493TW/womens.html",
    "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/womens.html",
    "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/womens.html",
    "/sports/size-charts/b/Yvette/womens.html",
    "/sports/size-charts/c/SPORTING_GOODS/womens.html"
  "mens": [
    "/sports/size-charts/a/B00EJ493TW/mens.html",
    "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/mens.html",
    "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/mens.html",
    "/sports/size-charts/b/Yvette/mens.html",
    "/sports/size-charts/c/SPORTING_GOODS/mens.html"
  "kids": [
    "/sports/size-charts/a/B00EJ493TW/kids.html",
    "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/kids.html",
    "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/kids.html",
    "/sports/size-charts/b/Yvette/kids.html",
    "/sports/size-charts/c/SPORTING_GOODS/kids.html"
__EOI__
print(Dumper(decode_json($json)));

Output:

$VAR1 = {
          'womens' => [
                        '/sports/size-charts/a/B00EJ493TW/womens.html',
                        '/sports/size-charts/b/Yvette/c/SPORTING_GOODS/womens.html',
                        '/sports/size-charts/c/SPORTING_GOODS/b/Yvette/womens.html',
                        '/sports/size-charts/b/Yvette/womens.html',
                        '/sports/size-charts/c/SPORTING_GOODS/womens.html'
          'mens' => [
                      '/sports/size-charts/a/B00EJ493TW/mens.html',
                      '/sports/size-charts/b/Yvette/c/SPORTING_GOODS/mens.html',
                      '/sports/size-charts/c/SPORTING_GOODS/b/Yvette/mens.html',
                      '/sports/size-charts/b/Yvette/mens.html',
                      '/sports/size-charts/c/SPORTING_GOODS/mens.html'
          'kids' => [
                      '/sports/size-charts/a/B00EJ493TW/kids.html',
                      '/sports/size-charts/b/Yvette/c/SPORTING_GOODS/kids.html',
                      '/sports/size-charts/c/SPORTING_GOODS/b/Yvette/kids.html',
                      '/sports/size-charts/b/Yvette/kids.html',
                      '/sports/size-charts/c/SPORTING_GOODS/kids.html'

The JSON you actually passed to JSON::XS is different. It contains &#34;women&#34; where you say it contains "women", for starters.

use strict;
use warnings;
use Data::Dumper qw( Dumper );
use JSON::XS     qw( decode_json );
my $json = <<'__EOI__';
  &#x34;womens&#x34;: [
    "/sports/size-charts/a/B00EJ493TW/womens.html",
    "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/womens.html",
    "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/womens.html",
    "/sports/size-charts/b/Yvette/womens.html",
    "/sports/size-charts/c/SPORTING_GOODS/womens.html"
  "mens": [
    "/sports/size-charts/a/B00EJ493TW/mens.html",
    "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/mens.html",
    "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/mens.html",
    "/sports/size-charts/b/Yvette/mens.html",
    "/sports/size-charts/c/SPORTING_GOODS/mens.html"
  "kids": [
    "/sports/size-charts/a/B00EJ493TW/kids.html",
    "/sports/size-charts/b/Yvette/c/SPORTING_GOODS/kids.html",
    "/sports/size-charts/c/SPORTING_GOODS/b/Yvette/kids.html",
    "/sports/size-charts/b/Yvette/kids.html",
    "/sports/size-charts/c/SPORTING_GOODS/kids.html"
__EOI__
print(Dumper(decode_json($json)));

Output:

'"' expected, at character offset 4 (before "&#x34;womens&#x34;: ...") at a.pl line 33.

JSON.pm is just a front-end for JSON::XS (if you have it installed) or JSON::PP (default).

It won't help to switch to JSON.pm since it'll just end up using JSON::XS. It won't help to use JSON::PP or any other JSON parser either; they won't be able to handle the corrupted JSON you have any more than JSON::XS can.

I submitted an edit to ikegami's answer, yesterday; but it hasn't shown up, so I guess it wasn't approved.

What I would suggest would be to start with ikegami's final version and add the following line near the top with the rest of the 'use' statements:

use HTML::Entities qw( decode_entities ) ;

Then all you have to do is update his final line of code to:

print( Dumper( decode_json( decode_entities( $json ) ) ) ) ;

and you'll get the result you're looking for.