Skip to content

Fix: xs:element default value ignored for simpleContent extension types - #285

Draft
Bergmann89 with Copilot wants to merge 2 commits into
masterfrom
copilot/fix-xs-boolean-default-value
Draft

Fix: xs:element default value ignored for simpleContent extension types#285
Bergmann89 with Copilot wants to merge 2 commits into
masterfrom
copilot/fix-xs-boolean-default-value

Conversation

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

When an xs:element carries default="false" and wraps an inline complex type with xs:simpleContent (e.g. extending xs:boolean), a self-closing element like <Bar Baz="xxxx"/> fails deserialization with UnknownOrInvalidValue("") — the default is never applied.

Root cause: Event::Empty (self-closing XML element) was passed directly to ContentDeserializer::init, which tried to parse an empty byte slice as a boolean. The default attribute from xs:element was never threaded through the pipeline to the generated deserializer.

Changes

  • ComplexMeta (models/meta/complex.rs): Add default: Option<String> field; include in TypeEq so types with different defaults remain distinct.
  • Interpreter (pipeline/interpreter/state/generate_types/variant_processor.rs): Propagate xs:element.defaultComplexMeta.default when building inline complex types.
  • Generator (pipeline/generator/data/complex.rs): Convert the default string to a ValueRendererBox; store it in ComplexDataContent.default_value. Thread a default: Option<&str> parameter through new(), new_simple(), and all call sites.
  • ComplexDataContent (models/data/complex.rs): Add default_value: Option<ValueRendererBox> field.
  • Defaults renderer (pipeline/renderer/steps/defaults.rs): Emit a pub fn default_content() -> T { … } associated function when default_value is set.
  • Deserializer renderer (pipeline/renderer/steps/quick_xml/deserialize.rs): In render_deserializer_fn_next_content_simple, intercept Event::Empty before calling ContentDeserializer — if a default exists, call default_content() and return immediately.

Generated output example

impl BarElementType {
    #[must_use]
    pub fn default_content() -> bool {
        false
    }
}

// In the generated deserializer:
S::Init__ => {
    if matches!(&event, Event::Empty(_)) {
        self.store_content(super::BarElementType::default_content())?;
        let data = self.finish(helper)?;
        return Ok(DeserializerOutput { artifact: DeserializerArtifact::Data(data), .. });
    }
    let output = ContentDeserializer::init(helper, event)?;
    self.handle_content(helper, output)
}

Thread `default` attribute from xs:element through meta-model, generator,
and renderer to produce `default_content()` and use it in the generated
deserializer for `Event::Empty` (self-closing element with no text content).

Changes:
- ComplexMeta: add `default: Option<String>` field
- Interpreter: propagate xs:element `default` to inline ComplexMeta
- Generator: pass default through to ComplexDataContent as ValueRendererBox
- Renderer (defaults.rs): render `default_content()` method
- Renderer (deserialize.rs): intercept Event::Empty and use default_content()
- New feature test for xs:boolean + simpleContent default
- Update ONIX expected output (also has an element with default)
Copilot AI changed the title [WIP] Fix issue with xs:boolean element ignoring default value Fix: xs:element default value ignored for simpleContent extension types Jul 24, 2026
Copilot AI requested a review from Bergmann89 July 24, 2026 11:48
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.

Element with extension base type "xs:boolean" ignores default value

2 participants