Skip to content

(bugfix) Quick xml defaultable choice with single option#262

Open
c-norm wants to merge 3 commits intoBergmann89:masterfrom
c-norm:quick-xml-defaultable-choice
Open

(bugfix) Quick xml defaultable choice with single option#262
c-norm wants to merge 3 commits intoBergmann89:masterfrom
c-norm:quick-xml-defaultable-choice

Conversation

@c-norm
Copy link
Copy Markdown

@c-norm c-norm commented Mar 28, 2026

There's a bug when using the quick_xml deserialization feature when determining what is Defaultable when you have an xs:choice with a single element in it.

Right now, when making the DefaultableCache, if you have a MetaTypeVariant::Choice with a single element in it, and that element is an ElementMode::Group then it assumes the Choice is Defaultable. But this isn't true, the single element inside the Choice must also be Defaultable.

I encountered this bug working with a schema called genericode. In it, there's type that basically boils down to an xs:choice with a single xs:sequence that has an xs:element in it.
Attached is a minimum schema to cause the issue:

choice-with-sequence.xml (github wouldn't let me attach an xsd?)

This breaks, because when deserializing the content of the Document, if it encounters nothing then it tries to make the enum that represents choice with the single value and then tries to construct a default value for the sequence, but the sequence does not implement Default.

My bug fix just checks if the type inside the Choice is itself defaultable. This worked for my use case and all the tests still passed locally

Copy link
Copy Markdown
Owner

@Bergmann89 Bergmann89 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @c-norm,

thanks for your contribution, I appreciate that. Could you please add a suitable integration test in the feature directory? You can use the XSD you have provided.

@c-norm
Copy link
Copy Markdown
Author

c-norm commented Mar 31, 2026

Wow that took a lot longer than I thought it would. I think all defaultable sequences were borked. I added a test case for an xs:choice with an xs:sequence that should be defaultable, and I'm glad I did because it didn't work! After a lot of testing I got it to work but I had to change more stuff:

  • quick_xml::deserialize::DefaultableCache::is_defaultable_element() will always return true if min_occurs is 0 (you would think this would have some ramifications but it didn't; all the other tests still pass and the generated code for all the other examples didn't change)
  • quick_xml::deserialize::ComplexDataElement::deserializer_enum_variant_default() won't use DeserializerHelper::finish_vec_default<T>() if min_occurs is 0, and instead just make an empty Vec without looking at the underlying type. finish_vec_default<T>() requires that the deserializer for whatever would go in the Vec implement Default, but you could very easily have an xs:sequence that is defaultable even if none of the elements in it are, so long as the minOccurs of the xs:sequence is 0

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

Successfully merging this pull request may close these issues.

2 participants