All,
Trying to build a generic utility capable of converting dictionary data into xml.
It uses a config table to define the relationships between XML nodes.
The following script is almost giving me the output. The script is generating First Child Element for each data item, resulting in repetition of that element. Please find my script and actual output below and help me with getting the expected output:
import xml.etree.ElementTree as ET
# Define the config_table and input_data
config_table = [
{'NODE_ID': 0, 'NODE_NAME': 'RootElement', 'NODE_TYPE': 'element', 'PARENT_ID': None, 'VALUE_FIELD': None, 'KEY_FIELD': 'KEY_ZERO'},
{'NODE_ID': 1, 'NODE_NAME': 'FirstChild', 'NODE_TYPE': 'element', 'PARENT_ID': 0, 'VALUE_FIELD': None, 'KEY_FIELD': 'KEY_ONE'},
{'NODE_ID': 2, 'NODE_NAME': 'SecondChild', 'NODE_TYPE': 'element', 'PARENT_ID': 1, 'VALUE_FIELD': None, 'KEY_FIELD': 'KEY_TWO'},
{'NODE_ID': 3, 'NODE_NAME': 'SecAtt', 'NODE_TYPE': 'attribute', 'PARENT_ID': 2, 'VALUE_FIELD': 'VALUE_THREE', 'KEY_FIELD': 'VALUE_THREE'},
{'NODE_ID': 4, 'NODE_NAME': 'ThirdChild', 'NODE_TYPE': 'text', 'PARENT_ID': 2, 'VALUE_FIELD': '', 'KEY_FIELD': 'VALUE_FOUR'},
]
input_data = [
{'KEY_ZERO': 1, 'KEY_ONE': 1, 'KEY_TWO': 1, 'VALUE_THREE': 'alpha', 'VALUE_FOUR': 'The first letter of the Greek alphabet'},
{'KEY_ZERO': 1, 'KEY_ONE': 1, 'KEY_TWO': 2, 'VALUE_THREE': 'beta', 'VALUE_FOUR': 'The second letter of the Greek alphabet'},
{'KEY_ZERO': 1, 'KEY_ONE': 1, 'KEY_TWO': 3, 'VALUE_THREE': 'gamma', 'VALUE_FOUR': 'The third letter of the Greek alphabet'},
{'KEY_ZERO': 1, 'KEY_ONE': 2, 'KEY_TWO': 4, 'VALUE_THREE': 'ay', 'VALUE_FOUR': 'The first letter of the English alphabet'},
{'KEY_ZERO': 1, 'KEY_ONE': 3, 'KEY_TWO': 5, 'VALUE_THREE': 'alif', 'VALUE_FOUR': 'The first letter of the Arabic alphabet'}
]
# Function to create XML from the config_table and input_data
def create_xml(config_table, input_data):
# Helper function to find node by ID
def find_node_by_id(node_id):
for node in config_table:
if node['NODE_ID'] == node_id:
return node
return None
# Helper function to build XML recursively
def build_xml(parent, parent_node_id, data):
for node in config_table:
if node['PARENT_ID'] == parent_node_id:
if node['NODE_TYPE'] == 'element':
element = ET.SubElement(parent, node['NODE_NAME'])
# Add KEY_FIELD attributes
#if node['KEY_FIELD'] in data:
#element.set(node['KEY_FIELD'], str(data[node['KEY_FIELD']]))
build_xml(element, node['NODE_ID'], data)
elif node['NODE_TYPE'] == 'attribute':
parent.set(node['NODE_NAME'], data[node['VALUE_FIELD']])
elif node['NODE_TYPE'] == 'text':
element = ET.SubElement(parent,node['NODE_NAME'])
element.text = data[node['KEY_FIELD']]
# Add KEY_FIELD attributes at each level
#if node['KEY_FIELD'] in data:
#parent.set(node['KEY_FIELD'], str(data[node['KEY_FIELD']]))
# Create the root element
root_node = find_node_by_id(0)
root = ET.Element(root_node['NODE_NAME'])
# Build the XML tree for each item in the input data
for data in input_data:
build_xml(root, 0, data)
# Convert the tree to a string
xml_str = ET.tostring(root, encoding='unicode', method='xml')
return xml_str
# Generate the XML
xml_output = create_xml(config_table, input_data)
print(xml_output)
Actual Output:
<RootElement>
<FirstChild>
<SecondChild SecAtt="alpha">
<ThirdChild>The first letter of the Greek alphabet</ThirdChild>
</SecondChild>
</FirstChild>
<FirstChild>
<SecondChild SecAtt="beta">
<ThirdChild>The second letter of the Greek alphabet</ThirdChild>
</SecondChild>
</FirstChild>
<FirstChild>
<SecondChild SecAtt="gamma">
<ThirdChild>The third letter of the Greek alphabet</ThirdChild>
</SecondChild>
</FirstChild>
<FirstChild>
<SecondChild SecAtt="ay">
<ThirdChild>The first letter of the English alphabet</ThirdChild>
</SecondChild>
</FirstChild>
<FirstChild>
<SecondChild SecAtt="alif">
<ThirdChild>The first letter of the Arabic alphabet</ThirdChild>
</SecondChild>
</FirstChild>
</RootElement>
Expected output:
<RootElement>
<FirstChild>
<SecondChild SecAtt="alpha">
<ThirdChild>The first letter of the Greek alphabet</ThirdChild>
</SecondChild>
<SecondChild SecAtt="beta">
<ThirdChild>The second letter of the Greek alphabet</ThirdChild>
</SecondChild>
<SecondChild SecAtt="gamma">
<ThirdChild>The third letter of the Greek alphabet</ThirdChild>
</SecondChild>
</FirstChild>
<FirstChild>
<SecondChild SecAtt="ay">
<ThirdChild>The first letter of the English alphabet</ThirdChild>
</SecondChild>
</FirstChild>
<FirstChild>
<SecondChild SecAtt="alif">
<ThirdChild>The first letter of the Arabic alphabet</ThirdChild>
</SecondChild>
</FirstChild>
</RootElement>
New contributor
user1386812 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.