2

How to parse YAML file and create a XML template?

I have a yaml file file which looks like below:

    ElementAttr1Format: basic
    ElementAttr1Name: Common Name
    ElementAttr1Updated: true
    ElementAttr1Value:
      Derived: 
        Name: field1
        Provider: profile
        Shared: false
        Value: displayName
      FieldNum: 13
    ElementAttr2Format: basic
    ElementAttr2Name: Email Address
    ElementAttr2Value:
      Derived: 
        Name: field2
        Provider: profile
        Shared: false
        Value: mail
      FieldNum: 7

I want to parse this YAML file and find in resultant dictionary all keys which are like "ElementAttrName". Map all dictionary values identified by creating a xml template for those identified keys in yaml with their values mapped to a specific xml value.

For Ex-

yaml attr xml value
mail email
common name cn

So, I have to maintain this map for each specified key identified in yaml which needs to be mapped to a specific xml value when creating a template.

I am maintaining the yaml and corresponding value as a dataframe now. Below is code snippet for same.

attrmap = {
    "yamlattr" : ["Email Address,Last Name","First Name","Department","Common Name"]
    "xmlValue" : ["mail","sn","givenName","dept","cn"]
}

Sample XML Template:

<root>
    <child alias="/an">
      <Attribute name="map">
           <Value>mail=email</Value>
           <Value>Common Name=cn</Value>
      </Attribute>
     </child>
</root>

Can someone please suggest me with an approach or a sample example with doc. which I can refer to so that I can implement the same for my use case.

  • 1
    where do the values `cn` and `email` come from? – JonSG May 24 '23 at 14:50
  • @JonSG These values are something we need to map. Like we want to assign or hardcode this value when some key is identified in yaml. – Karan Nayyar May 24 '23 at 16:54
  • If you can create that dataframe then you can use it like this to create the xml tree https://stackoverflow.com/questions/75751181/turn-nested-python-dictionary-into-xml – JonSG May 24 '23 at 17:20

1 Answers1

0

YAML documents essentialy consists of mappings (that are loaded as Python dicts), sequences (Python: list) and scalar values. The keys and values for mappings and the elements for sequences can consists of any of these three elements.

Although your example only consists of mappings that have scalars as keys and scalars or mappings as value, it is relatively easy to make a generic function that traverses the complete set of possibilities and insert the logic for gathering what you need in there.

Assuming your YAML document is in the file input.yaml:

import re
from pathlib import Path
import ruamel.yaml

file_in = Path('input.yaml')

pattern = re.compile(r'ElementAttr\d+Name$')

def gather(d, result):
    if isinstance(d, dict):
        for k, v in d.items():
            # The following is specific for finding the keys you are intersted in
            if isinstance(k, str) and pattern.match(k):
                result.setdefault(v, []). append(k)
            gather(k, result) # the key can be a collection node
            gather(v, result)
    elif isinstance(d, list):
        for elem in d:
            gather(elem, result)

    
yaml = ruamel.yaml.YAML()
data = yaml.load(file_in)
result = {}  
gather(data, result)
for k in result:
    print(f'found: {k.lower()!r}, nr keys: {len(result[k])}')

which gives:

found: 'common name', nr keys: 1
found: 'email address', nr keys: 1

The result dict does have the keys you are interested in as keys. BTW YAML has no attributes, that word is not even used in the YAML spec.

I would have included how to generate the actual XML, if it has been more clear how your hardcoded mapping from YAML would look like, but without any code in your question that is to much guesswork. The above should be enough to get you going.

Anthon
  • 69,918
  • 32
  • 186
  • 246
  • @Anton thanks for helping out. I am maintain the hardcoded mapping from YAML as a dataframe . I have added the same in the question post. Maybe this helps. I think will need to use xmltree for this. If you can help nudge me with a code or approach about how I can go about this that will help a great deal. – Karan Nayyar May 26 '23 at 07:34