Skip to content

Boolean types are not converted to their XML equivalents. #118

@jbourquin

Description

@jbourquin

Describe the bug
When converting a JSON object with boolean type values, Json2xml is not converting the values to their XML equivalents. Json2xml should be exporting the values in the XML as the lowercase words true and false respectively. Instead, Json2xml is exporting them as Python boolean types using the capitalized words True and False.

To Reproduce
Steps to reproduce the behavior:

  1. Given the following JSON object:
{
      "boolean": true,
      "boolean_dict_list": [
        {"boolean_dict": {"boolean": true}},
        {"boolean_dict": {"boolean": false}}
      ],
      "boolean_list": [true, false]
}
  1. Calling the Json2xml conversion like so:
xml = json2xml.Json2xml(sample_json, pretty=True).to_xml()
  1. Produces the following XML:
<all>
        <boolean type="bool">True</boolean>
        <boolean_dict_list type="list">
                <item type="dict">
                        <boolean_dict type="dict">
                                <boolean type="bool">True</boolean>
                        </boolean_dict>
                </item>
                <item type="dict">
                        <boolean_dict type="dict">
                                <boolean type="bool">False</boolean>
                        </boolean_dict>
                </item>
        </boolean_dict_list>
        <item type="bool">True</item>
        <item type="bool">False</item>
</all>

Notice all the boolean values are capitalized instead of being lowercase like they should be in XML and JSON. There also seems to be a problem with the boolean_list array, it is missing its parent tag.

Expected behavior

Json2xml should produce an XML string that looks like this:

<all>
        <boolean type="bool">true</boolean>
        <boolean_dict_list type="list">
                <item type="dict">
                        <boolean_dict type="dict">
                                <boolean type="bool">true</boolean>
                        </boolean_dict>
                </item>
                <item type="dict">
                        <boolean_dict type="dict">
                                <boolean type="bool">false</boolean>
                        </boolean_dict>
                </item>
        </boolean_dict_list>
        <boolean_list type="list">
            <item type="bool">true</item>
            <item type="bool">false</item>
        </boolean_list>
</all>

Additional context

The problem with the capitalized boolean values is because of the following statements in the json2xml.dicttoxml module:

def convert(obj, ids, attr_type, item_func, cdata, item_wrap, parent="root"):
    """Routes the elements of an object to the right function to convert them
    based on their data type"""

    LOG.info(f'Inside convert(). obj type is: "{type(obj).__name__}", obj="{str(obj)}"')

    item_name = item_func(parent)

    # Booleans are converted using this function because a Python boolean is a subclass of Number
    if isinstance(obj, (numbers.Number, str)):
        return convert_kv(
            key=item_name, val=obj, attr_type=attr_type, attr={}, cdata=cdata
        )

    if hasattr(obj, "isoformat"):
        return convert_kv(
            key=item_name,
            val=obj.isoformat(),
            attr_type=attr_type,
            attr={},
            cdata=cdata,
        )

    # This is never evaluated because Python booleans are subclasses of Python integers
    if isinstance(obj, bool):
        return convert_bool(item_name, obj, attr_type, cdata)

Python booleans are subclasses of integers, so the boolean values are passed to convert_kv instead of convert_bool because an integer is also a numbers.Number. The following statements evaluate to True in Python:

# Booleans are integers
isinstance(True, int)

# Booleans are numbers
isinstance(True, numbers.Number)

# Booleans are booleans
isinstance(True, bool)

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions