Generate " | " in JSON to YML

Viewed 187

I have a json with format like below:

{"nlu": [
   {"intent": "Greeting", "examples": ["Hi","Hello"]},
   {"intent": "Bye", "examples": ["Good bye","Bye bye"]}
]}

I want to convert this json in to yml format like below:

nlu:
- intent: Greeting
  examples: |
     - Hi
     - Hello
- intent: Bye
  examples: |
     - Good bye
     - Bye bye

I also converted like this, but the "|" symbol (behind the "examples") is missing:

nlu:
- intent: Greeting
  examples:
     - Hi
     - Hello
- intent: Bye
  examples:
     - Good bye
     - Bye bye

Could you help me to solve this? I tried to automatically input data into RASA from a json format. Thank you very much!

1 Answers

| starts a YAML literal block scalar, thus everything inside it is a single string. You want that single string to also be encoded as YAML. This means that you have to do a two-step conversion:

  • convert all examples values to YAML and replace their original values with the generated YAML strings
  • dump the whole structure as YAML, rendering the examples strings as literal block scalars.

Here's a solution that does just that in Python:

import yaml, sys

input = """
{"nlu": [
   {"intent": "Greeting", "examples": ["Hi","Hello"]},
   {"intent": "Bye", "examples": ["Good bye","Bye bye"]}
]}
"""

class Literal(str):
    pass

def literal_presenter(dumper, data):
    return dumper.represent_scalar("tag:yaml.org,2002:str", data, style="|")
yaml.add_representer(Literal, literal_presenter)

content = yaml.safe_load(input)
for item in content["nlu"]:
  item["examples"] = Literal(yaml.dump(item["examples"]))

yaml.dump(content, sys.stdout, sort_keys=False)

To get PyYAML to dump the string as literal block scalar, it uses the class Literal and registers a custom representer for it.

The code is able to load the original JSON with PyYAML since YAML is a superset of JSON.

Output:

nlu:
- intent: Greeting
  examples: |
    - Hi
    - Hello
- intent: Bye
  examples: |
    - Good bye
    - Bye bye
Related