Converts XML into JSON/Python dicts/arrays and vice-versa using multiple conventions
Cobra convention uses 'attributes' and 'children' keys with sorted attributes and string-only values. It ensures consistent attribute ordering and preserves all values as strings for predictable data handling.
Creates a Cobra converter with sorted attributes and string preservation.
class Cobra(XMLData):
def __init__(self, **kwargs):
"""
Initialize Cobra converter.
Parameters:
- **kwargs: Additional XMLData parameters (xml_fromstring, xml_tostring,
element, dict_type, list_type, simple_text, invalid_tags)
Note: xml_fromstring defaults to False (string preservation)
"""Converts Python dictionaries and lists to XML elements using Cobra convention structure with explicit 'attributes' and 'children' handling.
def etree(self, data, root=None):
"""
Convert data structure into a list of etree.Element using Cobra format.
Cobra etree() expects specific structure:
- Dictionary values must have 'attributes' key (dict of attributes)
- Dictionary values may have 'children' key (list of child elements)
- Simple string values become element text content
- Attributes from 'attributes' dict are set on XML element
- Children from 'children' list are recursively processed
Parameters:
- data: dict or list, data structure with Cobra format:
- {"element": {"attributes": {...}, "children": [...]}}
- {"element": "text"} for simple text elements
- root: Element, optional root element to append to
Returns:
List of etree.Element objects or modified root element
"""Converts XML elements to Python dictionaries using Cobra convention with sorted attributes and structured output.
def data(self, root):
"""
Convert etree.Element into a dictionary using Cobra convention.
Cobra convention produces consistent output:
- 'attributes': Always present (sorted alphabetically, even when empty)
- 'children': List of child elements and text content (when present)
- Text-only elements: Become direct string values (flattened)
- String preservation: All values remain as strings (xml_fromstring=False)
- Merge behavior: Adjacent text and single elements may be merged
Parameters:
- root: Element, XML element to convert
Returns:
dict: Dictionary with element name as key and structured value:
- Simple text: {"element": "text"}
- Complex: {"element": {"attributes": {...}, "children": [...]}}
- Attributes dict always sorted by key
"""Usage Examples:
from xmljson import cobra
from xml.etree.ElementTree import fromstring, tostring
import json
# XML to data conversion (attributes always sorted)
xml_string = '<item zebra="z" alpha="a" beta="b"><title>Sample</title><count>42</count></item>'
xml_element = fromstring(xml_string)
data = cobra.data(xml_element)
print(json.dumps(data, indent=2))
# Output:
# {
# "item": {
# "attributes": {
# "alpha": "a",
# "beta": "b",
# "zebra": "z"
# },
# "children": [
# {"title": "Sample"},
# {"count": "42"}
# ]
# }
# }
# Data to XML conversion
data = {
'item': {
'attributes': {'id': '123', 'type': 'book'},
'children': [
{'title': 'Python Guide'},
{'author': 'John Doe'}
]
}
}
elements = cobra.etree(data)
print(tostring(elements[0]).decode())
# Output: <item id="123" type="book"><title>Python Guide</title><author>John Doe</author></item>cobra: CobraA pre-configured Cobra instance available at module level for immediate use.
{
"element": {
"attributes": {"attr1": "value1", "attr2": "value2"}, # Always sorted
"children": [
{"child1": "text"},
{"child2": "more text"}
]
}
}{
"element": {
"attributes": {}, # Always present, even when empty
"children": [...]
}
}{"element": "text content"} # Flattened when no attributes/childrenfrom xmljson import cobra, abdera
from xml.etree.ElementTree import fromstring
import json
xml_string = '<item beta="2" alpha="1"><title>Test</title></item>'
xml_element = fromstring(xml_string)
# Cobra: sorted attributes, strings only
cobra_data = cobra.data(xml_element)
print("Cobra:", json.dumps(cobra_data))
# Output: Cobra: {"item": {"attributes": {"alpha": "1", "beta": "2"}, "children": [{"title": "Test"}]}}
# Abdera: unsorted attributes, type conversion
abdera_data = abdera.data(xml_element)
print("Abdera:", json.dumps(abdera_data))
# Output: Abdera: {"item": {"attributes": {"beta": 2, "alpha": 1}, "children": [{"title": "Test"}]}}