Dhruv Ratan Gupta Dhruv Ratan Gupta - 3 months ago 18
YAML Question

YAML appending DATA within a file

I have a YAML file of this sort:

Main_part1:
label1: Main PArt1


Main_part2:
label2: Main Part2


A_part1:
label3: part1 of A

A_part2:
label4: part 2 of A

B_part1:
label5: this is part 1 of B

B_part2:
label6: this is part 2 of B


I have an html file with 2
<div>
tags for A and B. Whenever A is clicked, contents of
A_part1
should append to
Main_part1
and
A_part2
should append to contents of
Main_part2
. Similarly for B. And send a response back to web page that contents of A/B added.

Finally, I want to Create a final YAML file merging
Main_Part1
and
Main_Part2
.

Any sort of solution(Java/Python etc) can be used.

I have created different labels to show that inside info in all blocks are different. As an example:

Say you click A, YAML file will look like:

Main_part1:
label1: Main PArt1
label3: part1 of A
Main_part2:
label2: Main Part2
label4: part 2 of A

A_part1:
label3: part1 of A

A_part2:
label4: part 2 of A

B_part1:
label5: this is part 1 of B

B_part2:
label6: this is part 2 of B


And then a final YAML file merging
Main_part1
and
Main_part2
.

Answer

The keys as you have them don't really work that well for this operation, so the best thing to do is parse the keys of the toplevel key to an alternate dictionary, with keys pointing to the same (dictionary) values as the original mapping/dict:

import sys
import ruamel.yaml

yaml_str = """\
Main_part1:
   label1: Main PArt1
Main_part2:
   label2: Main Part2
A_part1:
  label3: part1 of A
A_part2:
   label4: part 2 of A
B_part1:
    label5: this is part 1 of B
B_part2:
  label6: this is part 2 of B
"""

data = ruamel.yaml.round_trip_load(yaml_str)
alt = {}
for key in data:
    section, part = key.split('_')
    alt[(section, part)] = data[key]
alt[('Main', 'part1')].update(alt[('Main', 'part2')])

after that you need a little helper, call it and dump the original:

def collapse(collapse_key):
    for key in alt:
        if key[0] == collapse_key:
            alt[('Main', key[1])].update(alt[key])

collapse('A')  # <- this should be a parameter to your script based on the click.

ruamel.yaml.round_trip_dump(data, sys.stdout)

gives:

Main_part1:
  label1: Main PArt1
  label3: part1 of A
  label2: Main Part2
  label4: part 2 of A
Main_part2:
  label2: Main Part2
  label4: part 2 of A
A_part1:
  label3: part1 of A
A_part2:
  label4: part 2 of A
B_part1:
  label5: this is part 1 of B
B_part2:
  label6: this is part 2 of B

It would of course be somewhat easier if you created the keys in a way that you are going to use them (i.e. with two elements):

(Main, part1):
   label1: Main PArt1
(Main, part2):
   label2: Main Part2
(A, part1):
  label3: part1 of A
(A, part2):
   label4: part 2 of A
(B, part1):
    label5: this is part 1 of B
(B, part2):
  label6: this is part 2 of B

the above is perfectly fine YAML, although not accepted by all parsers.

Comments