Josh Williams
Josh Williams

Reputation: 87

How to converted indented .yaml files to json using Python?

Currently I am working on a project where I'd need to convert multiple .yaml filse to .json in order to work with it.

Example .yaml-file:

id: 1
name: Tony
created: ruby/object:ActiveSupport::TimeWithZone
  zone: utc
  time: 10:00:00
updated: ruby/object:ActiveSupport::TimeWithZone
  zone: utc
  time: 10:00:01

However, when I try to convert it using this script:

python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), 
sys.stdout, indent=4)' < test.yaml > test.json

I returns this error:

expected <block end>, but found '?' in "<stdin>", line 9, column 5

Edit 1: changed .yaml file example (created_at)

Upvotes: 0

Views: 4036

Answers (2)

Anthon
Anthon

Reputation: 76912

Your input is incorrect YAML as you cannot have a key/value pair:

created: ruby/object:ActiveSupport::TimeWithZone

that is not indented, followed by an indented key/value pair:

  zone: utc

The probable cause for this is that you left out the ! introducing the tag for a ruby object. You should get rid of the full ruby/object:ActiveSupport::TimeWithZone.

That you get the message that colons are not allowed in scalars is because PyYAML doesn't support ':' in string scalars (ruby/object:ActiveSupport::TimeWithZone) even if that colon is not followed by a space. I recommend you update to ruamel.yaml (which supports YAML 1.2 and many more things. Disclaimer: I am the author of that package). You should also use '.safe_load()' instead of `.load()' (which is not safe to use!)

Given this correct YAML input:

id: 1
name: Tony
created: 
  zone: utc
  time: 10:00:00
updated: 
  zone: utc
  time: 10:00:01

and running:

python -c 'import sys, ruamel.yaml, json; json.dump(ruamel.yaml.safe_load(sys.stdin), sys.stdout, indent=4)' < test.yaml

you will get:

{
    "updated": {
        "zone": "utc", 
        "time": 36001
    }, 
    "id": 1, 
    "name": "Tony", 
    "created": {
        "zone": "utc", 
        "time": 36000
    }

Upvotes: 0

McGrady
McGrady

Reputation: 11487

Maybe the yaml file should be like this:

id: 1
name: Tony
created:
  zone: utc
  time: '2016-11-24 10:00:00'
updated:
  zone: utc
  time: '2016-11-24 10:00:01'

And run this code:

with open('test.yaml') as f:       
    dataMap = yaml.safe_load(f) 
    print (json.dumps(dataMap)) 

And you will get :

{"updated": {"zone": "utc", "time": "2016-11-24 10:00:01"}, "id": 1, "name": "Tony", "created": {"zone": "utc", "time": "2016-11-24 10:00:00"}}

Hope this helps.

Upvotes: 4

Related Questions