Fix: Only emit xmlns:xsi on root elements when nillable elements exist in the dependency tree#258
Conversation
- Add `nillable_deps` cache and `has_nillable_elements` method to NamespaceCollector - Fix `get_namespaces_impl` to only add XSI namespace when Reference.nillable=true or when an element in a Sequence/All/Choice has nillable=true - Fix `need_xsi_namespace` check to also verify the type has nillable elements - Update expected test files to reflect the correct behavior Co-authored-by: Bergmann89 <2215174+Bergmann89@users.noreply.github.com>
Co-authored-by: Bergmann89 <2215174+Bergmann89@users.noreply.github.com>
Bergmann89
left a comment
There was a problem hiding this comment.
@copilot instead of implementing special handling for the XSI namespace we should simply integrate it in the normal namespace handling of the NamespaceCollector, so that NamespaceCollector::get_namespaces simply contains it if needed.
…ling Remove separate has_nillable_elements/provides_xsi_namespace methods and the need_xsi_namespace special path. XSI is now integrated into get_namespaces_impl naturally: it is added to the namespace state only when a Reference is nillable or an All/Choice/Sequence element is nillable. The global_xmlns iteration in the caller then emits it automatically. Co-authored-by: Bergmann89 <2215174+Bergmann89@users.noreply.github.com>
Done in b71d221. Removed |
Bergmann89
left a comment
There was a problem hiding this comment.
Looks better now, but what about integration tests?
Check xsd-parser/tests/feature/nillable and xsd-parser/tests/feature/nillable_dynamic_types.
All 13 integration tests in both |
Bergmann89
left a comment
There was a problem hiding this comment.
Yes, the existing tests are all ok, but you should also add tests that cover the edge case from the issue (that nilable support is enabled, but the namespace is only emitted if the element or any dependency needs it)
…ble dependencies must not emit xmlns:xsi Co-authored-by: Bergmann89 <2215174+Bergmann89@users.noreply.github.com>
Added in 6412736. The |
When
NILLABLE_TYPE_SUPPORTis enabled, every generated root-element serializer unconditionally emitsxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"— even for schemas with no nillable elements at all. This pollutes the namespace context and breaks serialize/deserialize round-trips forxs:anycontent.Changes
serialize.rs—NamespaceCollectorget_namespaces_impl— removed the unconditionaladd_ns(XSI)block; XSI is now only added to the namespace state when aReferenceis nillable or a group element hasnillable: true. This integrates XSI into the normal namespace handling so thatget_namespacesnaturally contains it when needed.need_xsi_namespace/xsicode path,provides_xsi_namespace, and associated helper methods are no longer needed; the existingglobal_xmlnsiteration emitswrite_xmlns(XSI)automatically when XSI appears in the namespace map returned byget_namespaces.Before, XSI was unconditionally added to every type's namespace state:
After, XSI is only added when nillable elements are actually present:
Updated expected test files (7 files)
Corrected generated output for types with no nillable elements across
defaultable_content,mixed_choice_with_any,override_,redefine,nillable_dynamic_types(intermediate/final types), andmusicxml(231 types were incorrectly emitting XSI). Types with actual nillable elements (e.g.,FooType,ListType) are unchanged.Integration tests for the edge case
Added a
BarType/Barelement (no nillable children) to thenillablefeature test schema to explicitly cover the edge case wherenillable_type_supportis enabled globally but a root element has no nillable elements in its dependency tree:example/bar.xml— expected serialization ofBarwith noxmlns:xsiattribute.write_quick_xml— verifiesBardoes not emitxmlns:xsieven withnillable_type_supportenabled, whileFooandNillableFoocontinue to emit it correctly.read_quick_xml— verifies the round-trip forBarworks against an XML file withoutxmlns:xsi.Original prompt
💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.