Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nillable fields are skipped by XmlSerializer #408

Closed
barsv opened this issue Feb 12, 2021 · 5 comments
Closed

nillable fields are skipped by XmlSerializer #408

barsv opened this issue Feb 12, 2021 · 5 comments

Comments

@barsv
Copy link

barsv commented Feb 12, 2021

Hi,

I have nillable="true" in my xsd. I generated a python class for this xsd. I serialize the class into xml using XmlSerializer. My problem is that the nillable field is missing in the xml.
I have

            "required": True,
            "nillable": True,

in the generated code for the nillable field. So I think that XmlSerializer should generate an empty tag for this field.

I don't know if it's a bug or not. Could you please suggest.

More details:

I created a small repo to reproduce: https://github.com/barsv/xsdata-issue.git

My test.xsd file:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="shiporder">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="name" nillable="true" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

I generated test.py using xsdata test.xsd:

@dataclass
class Shiporder:
    class Meta:
        name = "shiporder"

    name: Optional[str] = field(
        default=None,
        metadata={
            "type": "Element",
            "namespace": "",
            "required": True,
            "nillable": True,
        }
    )

I serialize it using the following code:

config = SerializerConfig(pretty_print=True)
xml_serializer = XmlSerializer(config=config)

order = Shiporder()
#order.name = "test"
xml = xml_serializer.render(order)
print(xml)

and I get the following xml:

<?xml version="1.0" encoding="UTF-8"?>
<shiporder/>

This xml doesn't pass validation against the original xsd.

I would expect to get the following xml instead:

<?xml version="1.0" encoding="UTF-8"?>
<shiporder>
    <name/>
</shiporder>

ps: I'm not an expert in neither xsd nor python.

@tefra
Copy link
Owner

tefra commented Feb 12, 2021

Initialize the field with an empty string.

order = Shiporder()
order.name = ""
xml = xml_serializer.render(order)
print(xml)
<?xml version="1.0" encoding="UTF-8"?>
<shiporder>
  <name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</shiporder

That's the parser's behavior as well

obj = XmlParser().from_string(xml, Shiporder)
print(obj)
# Shiporder(name='')

It seems a bit weird I agree and I can't really remember right now why I had to do it this way, I am going to take another look again.

@tefra
Copy link
Owner

tefra commented Feb 12, 2021

I took out this behavior and run the w3c test suite, everything passed as expected, I still can't remember why I had to do that.

Thanks for reporting @barsv

@barsv
Copy link
Author

barsv commented Feb 13, 2021

Thank you! The empty string works good for me.

I want to add for others who might find this issue ticket in the future that the same workaround works for XmlDateTime as well.
I changed the type of the field from xs:string to xs:dateTime, regenerated the class, deserialized it using XmlParser from xml with empty tag and ... to my surprise I found that the field value in the deserialized object is empty string. And when I serialized the object back to xml it generated the empty tag and validates perfectly against the xsd.

I don't know if the issue should be closed though because the field type in the data class is name: Optional[XmlDateTime] =... while the value after deserialization is empty string. I would expect to have None instead of empty string.

@tefra
Copy link
Owner

tefra commented Feb 13, 2021

No leave it open I am planning to change this behavior in the next release, to avoid the empty string hack I just need to test a few more things

@tefra tefra closed this as completed in 21389da Feb 15, 2021
@tefra
Copy link
Owner

tefra commented Feb 15, 2021

Thank you for reporting @barsv the fix is on master and will be included in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants