From 757b82249e3c2cf0bcf063d4bd7a86e2174c67bc Mon Sep 17 00:00:00 2001 From: Jeroendevr Date: Wed, 18 Jan 2023 12:13:29 +0100 Subject: [PATCH] Merge pull request #169 * Default is False for list_headers * List items with attrs test * Merge branch 'master' into list_attrs * Merge branch 'master' into list_attrs * fix flake8 issues * Merge branch 'master' into list_attrs * create attr test * remove test from other branch * Merge branch 'master' into attr_test * working test with attriubute list and updated docs --- json2xml/dicttoxml.py | 43 ++++++++++++++++++++++++++---- tests/test_dict2xml.py | 60 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 95 insertions(+), 8 deletions(-) mode change 100755 => 100644 json2xml/dicttoxml.py diff --git a/json2xml/dicttoxml.py b/json2xml/dicttoxml.py old mode 100755 new mode 100644 index 568a305..422403b --- a/json2xml/dicttoxml.py +++ b/json2xml/dicttoxml.py @@ -244,7 +244,7 @@ def dict2xml_str( if attr_type: attr["type"] = get_xml_type(item) - attr = item.pop("@attrs", attr) # update attr with custom @attr if exists + val_attr: dict[str, str] = item.pop("@attrs", attr) # update attr with custom @attr if exists rawitem = item["@val"] if "@val" in item else item if is_primitive_type(rawitem): if type(rawitem) == str: @@ -256,12 +256,17 @@ def dict2xml_str( subtree = convert( rawitem, ids, attr_type, item_func, cdata, item_wrap, item_name, list_headers=list_headers ) + if parentIsList and list_headers: + if len(val_attr) > 0 and not item_wrap: + attrstring = make_attrstring(val_attr) + return f"<{parent}{attrstring}>{subtree}" + # should not return if there is an attr present return f"<{parent}>{subtree}" elif item.get("@flat", False) or (parentIsList and not item_wrap): return subtree - attrstring = make_attrstring(attr) + attrstring = make_attrstring(val_attr) return f"<{item_name}{attrstring}>{subtree}" @@ -413,7 +418,7 @@ def convert_list( output: list[str] = [] addline = output.append - item_name = item_func(parent) + item_name = item_func(parent) # Is item_name still relevant if item_wrap is false if item_name.endswith("@flat"): item_name = item_name[:-5] this_id = None @@ -470,7 +475,13 @@ def convert_list( elif isinstance(item, dict): addline( dict2xml_str( - attr_type, attr, item, item_func, cdata, item_name, item_wrap, + attr_type=attr_type, + attr=attr, + item=item, + item_func=item_func, + cdata=cdata, + item_name=item_name, + item_wrap=item_wrap, parentIsList=True, parent=parent, list_headers=list_headers @@ -583,7 +594,29 @@ def dicttoxml( :param bool item_wrap: Default is True - specifies whether to nest items in array in + specifies whether to nest items in array in Example if True + + ..code-block:: python + + data = {'bike': ['blue', 'green']} + + .. code-block:: xml + + + blue + green + + + Example if False + + ..code-block:: python + + data = {'bike': ['blue', 'green']} + + ..code-block:: xml + + blue + green' :param item_func: items in a list. Default is 'item' diff --git a/tests/test_dict2xml.py b/tests/test_dict2xml.py index c51f78b..27e9fc2 100644 --- a/tests/test_dict2xml.py +++ b/tests/test_dict2xml.py @@ -61,6 +61,16 @@ def test_dict2xml_xsi_xmlns(self): 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.w3schools.com">' \ 'blue' == result + def test_item_wrap_true(self): + data = {'bike': ['blue', 'green']} + result = dicttoxml.dicttoxml(obj=data, root=False, attr_type=False, item_wrap=True) + assert result == b'bluegreen' + + def test_item_wrap_false(self): + data = {'bike': ['blue', 'green']} + result = dicttoxml.dicttoxml(obj=data, root=False, attr_type=False, item_wrap=False) + assert result == b'bluegreen' + def test_dict2xml_with_flat(self): data = {'flat_list@flat': [1, 2, 3], 'non_flat_list': [4, 5, 6]} result = dicttoxml.dicttoxml(data, attr_type=False) @@ -98,9 +108,40 @@ def test_dict2xml_with_ampersand(self): def test_dict2xml_with_ampsersand_and_attrs(self): dict_with_attrs = {'Bicycles': {'@attrs': {'xml:lang': 'nl'}, '@val': 'Wheels & Steers'}} root = False - attr_type = False assert 'Wheels & Steers' == dicttoxml.dicttoxml( - dict_with_attrs, root=root, attr_type=attr_type).decode('UTF-8') + dict_with_attrs, root=root, attr_type=False).decode('UTF-8') + + def test_dict2xml_list_items_with_attrs(self): + ''' + Currently has an item wrap because item_name = 'item' this should not be the case with item_wrap as False + ''' + dict_with_attrs = { + 'transportation-mode': [ + { + '@attrs': {'xml:lang': 'nl'}, + '@val': 'Fiets' + }, + { + '@attrs': {'xml:lang': 'nl'}, + '@val': 'Bus' + }, + { + '@attrs': {'xml:lang': 'en'}, + '@val': 'Bike' + } + ] + } + wanted_xml_result = b'Fiets' \ + b'Bus' \ + b'Bike' + xml_result = dicttoxml.dicttoxml( + dict_with_attrs, + root=False, + attr_type=False, + item_wrap=False, + list_headers=True) + + assert xml_result == wanted_xml_result def test_make_id(self): make_id_elem = dicttoxml.make_id("li") @@ -164,7 +205,12 @@ def test_list_headers(self): {'frame_color': 'red'}, {'frame_color': 'green'} ]} - result = dicttoxml.dicttoxml(dict, root=False, item_wrap=False, attr_type=False, list_headers=True) + result = dicttoxml.dicttoxml( + dict, + root=False, + item_wrap=False, + attr_type=False, + list_headers=True) print(result) assert b'redgreen' == result @@ -223,3 +269,11 @@ def test_dict2xml_issue_151(self): result = dicttoxml.dicttoxml(data, root=False, attr_type=False) print(result) assert b'1' == result + + def test_dict2xml_attr_type(self): + data = {'bike': 'blue'} + result = dicttoxml.dicttoxml( + data, + root=False, + attr_type=True) + assert b'blue' == result