########## 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: .. code:: python from xml2vhdl.xml2dict import Xml2Dict Initialise the Xml2Dict class. Here you have the following options: .. list-table:: :header-rows: 1 * - 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: .. code:: python 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: .. list-table:: :header-rows: 1 * - 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: .. code:: python 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 ===== .. list-table:: :header-rows: 1 * - Attribute - Type - Description * - id - str - node id string, directly from XML, see :ref:`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 :ref:`generated_output` for details * - byte_size - int - see :ref:`generated_output` for details * - link_done - str - see :ref:`generated_output` for details * - absolute_offset - str - see :ref:`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 :ref:`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 ========= .. list-table:: :header-rows: 1 * - Attribute - Type - Description * - id - str - register id string, directly from XML, see :ref:`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 :ref:`generated_output` for details * - absolute_offset - str - see :ref:`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 :ref:`generated_output` for details * - missing_description - Bool - Current register is missing a description * - size - int - see :ref:`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) of the register mask * - missing_bitfield_description - bool - Any of the registers bitfields is missing a description * - field_list - List[dict] - see :ref:`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: 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. .. list-table:: :header-rows: 1 * - 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 ========= .. list-table:: :header-rows: 1 * - Attribute - Type - Description * - id - str - bitfield id string, directly from XML, see :ref:`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 ``""`` or ``"Missing description"``, it is replaced by ``""`` * - missing_description - bool - Current bitfield is missing a description * - type - str - is always "bitfield" for a bitfield dictionary * - absolute_id - str - see :ref:`generated_output` for details * - absolute_offset - str - see :ref:`generated_output` for details * - reset_value - str - reset_value of bitfield, directly from output xml * - mask - str - Capitalized Hex format (0x) 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_ * 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_``. 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.