fix: valid XSD generation with model-driven namespaces#718
Open
suleman-uzair wants to merge 7 commits into
Open
fix: valid XSD generation with model-driven namespaces#718suleman-uzair wants to merge 7 commits into
suleman-uzair wants to merge 7 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes invalid XSD output from to_xsd by explicitly binding the W3C XML Schema vocabulary to xmlns:xs and consistently emitting xs:-prefixed schema structure elements, while improving namespace qualification/import behavior for named types under target namespaces (regression coverage for #717).
Changes:
- Bind XSD vocabulary as
xmlns:xsand prefix emitted schema structure elements (xs:schema,xs:element,xs:complexType, etc.). - Qualify named-type QName references with the appropriate namespace prefix (target namespace or referenced model namespace), including collection cases, with cycle guards for recursive models.
- Add/adjust Nokogiri-load regression tests and update existing spec expectations to the new
xs:-prefixed structure output.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/lutaml/xml/schema/xsd_schema.rb | Implements xs:-prefixed schema element emission, namespace declaration/collection, QName qualification, import logic, and recursion guards. |
| spec/lutaml/model/schema/xsd_schema_spec.rb | Adds Nokogiri schema-load regression coverage for #717 and additional namespace edge cases. |
| spec/lutaml/model/xsd_type_validation_spec.rb | Updates expectations to reflect xs:schema + xmlns:xs binding. |
| spec/lutaml/model/xsd_patterns_spec.rb | Updates pattern-based XSD string expectations for xs:-prefixed structure elements. |
| spec/lutaml/model/xsd_form_default_patterns_spec.rb | Updates expectations for xs:-prefixed structure elements in generated schemas. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
added 2 commits
July 7, 2026 12:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes the invalid XSD produced by
Model.to_xsd, which referenced thexs:prefix without ever binding it, so no XSD processor could load theoutput. It binds the XML Schema vocabulary to
xmlns:xsand derives allnamespace handling from the models'
XmlNamespaceclasses, so schemas spanningmultiple namespaces are generated correctly.
What this changes
xmlns:xsand emitsxs:-prefixed structure elementsXmlNamespaceclasses and declaresxmlns:<prefix>for eachtargetNamespacefrom the root model and qualifies named-type references by their owning namespacexs:importfor foreign namespaces instead of folding their types into the root schematnsprefix when the target namespace declares noneA -> B -> A) against infinite recursion in validation and type generationType::Valuetype-namespace prefixing is left as a follow-up (documented in-code).closes #717