vinitkumar / json2xml

json to xml converter in python3
https://json2xml.readthedocs.io/
Other
98 stars 32 forks source link

not well-formed (invalid token) with custom attrs if attr value has a " character #172

Closed SaraFarron closed 1 year ago

SaraFarron commented 1 year ago

Describe the bug An error occurs if trying to add a custom attributes with " inside

To Reproduce Steps to reproduce the behavior:

from json2xml import json2xml

data = {
    "product": {
        "@attrs": {
            'attr_name': 'attr_value"'
        },
        "@val": [],
    },
}

print(
    json2xml.Json2xml(data, attr_type=False, item_wrap=False, root=False).to_xml()
)

Gives

not well-formed (invalid token): line 1, column 31
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 31

During handling of the above exception, another exception occurred:

  File "/home/sara/.../test.py", line 13, in <module>
    json2xml.Json2xml(data, attr_type=False, item_wrap=False, root=False).to_xml()
json2xml.utils.InvalidDataError: 

For some reason @attrs key is popped out of the dictionary, which might be not an expected behavior

Expected behavior An xml-like string

Desktop (please complete the following information):

vinitkumar commented 1 year ago

Thanks for reporting the issue. I will look into it and try to implement a fix for it.

vinitkumar commented 1 year ago

@SaraFarron I think I know what's going wrong. I am confirm that nothing goes wrong if you JSON is a valid string.

    def test_dict_attr_crash(self):
        data = data = {
            "product": {
                "@attrs": {
                    "attr_name": "attr_value",
                    "a": "b"
                },
                "@val": [],
            },
        }
        result = json2xml.Json2xml(data).to_xml()
        dict_from_xml = xmltodict.parse(result)
        assert dict_from_xml["all"]["product"]["@attr_name"] == "attr_value"
        assert dict_from_xml["all"]["product"]["@a"] == "b"

I added your JSON into a test and it just seems to work.

The issue with your JSON string is that you are adding the attrs in a ' quote.

{
    "product": {
        "@attrs": {
            'attr_name': 'attr_value"'
        },
        "@val": [],
    },
}

If you fix that, the data is like this:

 {
    "product": {
        "@attrs": {
            "attr_name": "attr_value"
        },
        "@val": [],
    },
}

It would just work

SaraFarron commented 1 year ago

Hm, I was thinking about json2xml replacing such characters with \" or &quote but on second thought you might be right that user should pass a valid json in the first place. Thanks for answering!