XML 2 Dict
XML2Dict is a Python utility which converts a final output XML to nested Python dictionaries, representing nodes, registers and bitfields.
You can provide custom Python functions to run at a node, register or bitfield level.
This can enable functions such as the ability to generate docs from a jinja template.
Usage
Ensure you import Xml2Dict into your python project:
from xml2vhdl.xml2dict import Xml2Dict
Initialise the Xml2Dict class. Here you have the following options:
Attribute |
Description |
|---|---|
custom_node_function |
function that runs at every node. Must only contain one input which is the node_dict |
custom_register_function |
function that runs at every register. Must only contain one input which is the register_dict |
custom_bitfield_function |
function that runs at every bitfield. Must only contain one input which is the bitfield_dict |
escape_function |
function that runs converts a string and escapes it for a particular language |
merge_registers |
bool to say if registers are going to be merged in the parsed output |
acronyms |
list of string words which are capitalized in the _hr formats |
substitutions |
list of tuple of key and values to substitute in the _hr formats |
An example can be seen here:
xml_to_dict = Xml2Dict(custom_node_function=custom_node_function,
custom_register_function=custom_register_function,
custom_bitfield_function=custom_bitfield_function,
escape_function=escape_rst,
merge_registers=True)
Then you can parse xml using the parse_xml_to_dict method with the following options:
Attribute |
Description |
|---|---|
xml_file_path |
path to final output xml, this is required |
collapse_level |
maximum number of levels of nested nodes |
An example can be seen here:
xml_to_dict.parse_xml_to_dict(xml_file_path, collapse_level=3)
Dictionary Keys
Here are a list of all attributes that a Node, register and Bitfield dict can have:
Nodes
Attribute |
Type |
Description |
|---|---|---|
id |
str |
node id string, directly from XML, see Generated Output for details |
type |
str |
is always “node” for a node dictionary |
path |
List[str] |
List of id to current node, excluding the current id |
node |
ElementTree.Element |
the current ElementTree.Element, that the node dict is based on |
hw_type |
str |
see Generated Output for details |
byte_size |
int |
see Generated Output for details |
link_done |
str |
see Generated Output for details |
absolute_offset |
str |
see Generated Output for details |
address |
str |
Capitalized Hex format of relative address e.g. 0x008A0000 |
absolute_address |
str |
Capitalized Hex format of absolute address e.g. 0x008A0000 |
absolute_id |
str |
see Generated Output for details |
path_hr |
List[str] |
Human readable format of path |
absolute_id_hr |
str |
Human readable format of absolute_id |
id_hr |
str |
Human readable format of id |
id_upper |
str |
Upper format of id |
id_lower |
str |
Lower format of id |
children_nodes |
List[dict] |
list of node dictionaries of child nodes |
children_registers |
List[dict] |
list of registers dictionaries of child registers |
children_missing_description |
Bool |
Any child register or nodes are missing a description |
children_missing_bitfield_description |
Bool |
Any child bitfields are missing a description, no matter the level |
has_bitfields |
Bool |
Any of the child registers has bitfields |
Registers
Attribute |
Type |
Description |
|---|---|---|
id |
str |
register id string, directly from XML, see Generated Output for details. If there are multiple merged registers, only gives the first id. |
path |
List[str] |
List of id to current register, excluding the current id |
register |
ElementTree.Element |
the current ElementTree.Element, that the register dict is based on |
type |
str |
is always “register” for a register dictionary |
name |
str |
id of merged together registers, e.g. register_<0..15> |
absolute_id |
str |
see Generated Output for details |
absolute_offset |
str |
see Generated Output for details |
address |
str |
Capitalized Hex format of relative address e.g. 0x008A0000 |
absolute_address |
str |
Capitalized Hex format of absolute address e.g. 0x008A0000 |
description |
str |
see Generated Output for details |
missing_description |
Bool |
Current register is missing a description |
size |
int |
see Generated Output for details |
type_name |
str |
Can be “register” or “look up table” |
adjusted_size |
int |
Number of Registers including both merged registers and entries in look up table |
software_permissions |
str |
Capitalized permissions. Replaces R with RO. |
reset_value |
str |
reset_value of register, directly from output xml |
bitfields |
List[dict] |
List of bitfield dictionaries |
bitfield_names |
List[str] |
List of bitfield names |
width |
int |
Width in bits of mask |
from_bit |
int |
First bit index, where the mask is high |
to_bit |
int |
Last bit index, where the mask is high |
mask |
str |
Capitalized Hex format (0x<mask>) of the register mask |
missing_bitfield_description |
bool |
Any of the registers bitfields is missing a description |
field_list |
List[dict] |
see field_list dict for details |
last_merged_register |
dict |
dictionary of last merged register |
nof_merged_register |
int |
Number of merged registers in current dictionary |
id_upper |
str |
upper format of id |
id_lower |
str |
lower format of id |
name_upper |
str |
upper format of name |
name_lower |
str |
lower format of name |
path_hr |
List[str] |
Human readable format of path |
absolute_id_hr |
str |
Human readable format of absolute_id |
id_hr |
str |
Human readable format of id |
name_hr |
str |
Human readable format of name |
field_list dict
A list of dictionaries containing all fields including unused ones. Unused fields have blank names. List starts from least significant bits to most.
Note
This assumes all registers are 32 bits.
Dictionary Attribute |
Type |
Description |
|---|---|---|
name |
str |
“” if unused, bitfield[“id”] if bitfield, register[“name”] if register field |
name_upper |
str |
“” if unused, bitfield[“id_upper”] if bitfield, register[“name_upper”] if register field |
name_lower |
str |
“” if unused, bitfield[“id_lower”] if bitfield, register[“name_lower”] if register field |
width |
str |
width of field in bits |
from_bit |
int |
integer value representing the from bit index of the field |
to_bit |
int |
integer value representing the to bit index of the field |
Bitfields
Attribute |
Type |
Description |
|---|---|---|
id |
str |
bitfield id string, directly from XML, see Generated Output for details |
path |
List[str] |
List of id to current bitfield, excluding the current id |
id_upper |
str |
Upper format of id |
id_lower |
str |
lower format of id |
bitfield |
ElementTree.Element |
the current ElementTree.Element, that the bitfield dict is based on |
description |
str |
description from xml, parsed through an custom escape function. If |
missing_description |
bool |
Current bitfield is missing a description |
type |
str |
is always “bitfield” for a bitfield dictionary |
absolute_id |
str |
see Generated Output for details |
absolute_offset |
str |
see Generated Output for details |
reset_value |
str |
reset_value of bitfield, directly from output xml |
mask |
str |
Capitalized Hex format (0x<mask>) of the register mask |
from_bit |
int |
First bit index, where the mask is high |
to_bit |
int |
Last bit index, where the mask is high |
width |
int |
Width in bits of mask |
software_permissions |
str |
Capitalized permissions. Replaces R with RO. |
path_hr |
List[str] |
Human readable format of path |
absolute_id_hr |
str |
Human readable format of absolute_id |
id_hr |
str |
Human readable format of id |
Formats
Human Readable Format
_hr is a Human readable format, which breaks up a string into words by splitting by . and _.
If the word matches any given acronyms, or acronym with an s, the acronym is capitalized.
If the word/words match any word/words in the substitutions list, the substitution is made.
The First letter of each word is capitalized. Any . are replaced with -.
Upper Format
_upper is a Upper format, with everything capitalized and "_" replaced with " ".
Lower Format
_upper is a Upper format, with everything lower case and "_" replaced with " ".
Merging Registers
If merge_registers is set to true, one register dictionary can hold the information for multiple registers.
Registers can be merged if:
in format name_<int>
are next to each other
have same bitfields
have consecutive integers
The id and description remain the id and description of the first register.
A name is changed from id to name_<int_from_first_reg..int_from_last_reg>.
Collapsing Nodes
The max number of nested dictionary levels can be set by the collapse_level.
When collapsing nodes, all id (both register and nodes) are replaced with . joining all ids of collapsed nodes and registers.
You can get a flat node by setting the collapse_level to 0.