MCPcopy Index your code
hub / github.com/Bergmann89/xsd-parser

github.com/Bergmann89/xsd-parser @xsd-parser-v1.5.2

Chat with this repo
repository ↗ · DeepWiki ↗ · release xsd-parser-v1.5.2 ↗ · + Follow
12,121 symbols 27,792 edges 615 files 271 documented · 2%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

A comprehensive library for parsing XML schemas and generating code based on them.

This project originated as a fork of xsd-parser-rs but has since evolved into a complete rewrite.

If you enjoy the project and would like to support my work, you can buy me a coffee or send a tip via PayPal. Thanks a lot! 😊

Crates.io License Crates.io Version Crates.io Total Downloads docs.rs Github CI Dependency Status

Overview

This library is built around a staged transformation pipeline that converts XML schemas into Rust source code. Each stage handles a specific level of abstraction and produces a well-defined intermediate representation. This makes the library highly flexible, testable, and suitable for advanced customization or tooling.

overview

Pipeline Stages

  1. Parsing: The parsing stage is handled by the Parser type. It loads XML schemas from files or URLs and uses pluggable Resolvers to fetch and preprocess schema definitions. The result is captured in a Schemas model, which stores namespaces, prefixes, and the raw schema structure needed for further processing.

  2. Interpreting:: Interpreting is carried out by the Interpreter. This stage analyzes the schema definitions stored in the Schemas model and converts them into normalized, abstract type descriptions. The resulting MetaTypes model encapsulates schema semantics such as complex types, enumerations, references, and groups in a language-agnostic form.

  3. Optimizing: Optimization is performed by the Optimizer, which takes the MetaTypes and applies structural transformations. These include deduplication, simplification of unions, merging cardinalities, and resolving typedef aliases. The goal is to prepare the type graph for idiomatic translation into Rust while reducing complexity.

  4. Generating: The generation step uses the Generator to transform the abstract types into Rust-specific type data. It produces the DataTypes model by attaching names, Rust derivations, trait support, and rendering metadata. These enriched types form the basis for later rendering while still preserving schema semantics.

  5. Rendering: Rendering is handled by the Renderer, which converts DataTypes into structured Rust code organized in a Module. It uses the RenderStep trait to define individual rendering steps. Several built-in steps are available, including support for serde or quick-xml. Users can also add custom RenderStep implementations to extend or modify the output.

Data Models

  • Schemas: This model is built by the Parser and contains the raw XML schema data, including namespaces, prefixes, and schema file content. It serves as the foundation for interpretation and supports multiple sources and resolver types.

  • MetaTypes: Generated by the Interpreter, this model contains language-neutral type definitions. It includes data like complex types, references, enumerations, and groupings derived from schema structure. It is suitable for introspection, transformation, and optimization.

  • DataTypes: Produced by the Generator, this model holds enriched Rust-specific type data. Each type includes metadata for layout, naming, derivations, and other traits required for rendering idiomatic Rust code. This is the core input for the rendering process.

  • Module: The final model is produced by the Renderer. It wraps the Rust source code output into a structured format, ready for file output or consumption as token streams. Modules support nested submodules, file splitting, and embedded metadata for customization.

Features

This library provides the following features:

  • Rust Code Generation: Convert any XML schema into Rust code.
  • Layered Architecture: Add user-defined code to manipulate type information or generated code.
  • User-Defined Types: Inject existing types into the generated code to reuse predefined structures.
  • serde Support: Generate code for serialization and deserialization using serde with serde_xml or quick_xml as serializer/deserializer.
  • quick_xml Support: Direct serialization/deserialization support using quick_xml, avoiding serde limitations and leveraging asynchronous features.

Planned Features

  • Schema-Based Validation: Generate validators directly from schemas to validate XML data during reading or writing.

Benchmark

Below you can find a list of some benchmarks for serializing and deserializing different XML documents for different schemas. For more details please have a look to the benchmark crate.

Schema Document Engine Op Min Avg Mdn Max Stack
XMLSchema XMLSchema quick_xml serialize 390.01 µs 418.67 µs 418.00 µs 467.08 µs 13.5 KiB
XMLSchema XMLSchema quick_xml deserialize 2.05 ms 2.10 ms 2.10 ms 2.17 ms 146.6 KiB
XMLSchema (boxed) XMLSchema quick_xml deserialize 1.79 ms 1.94 ms 1.93 ms 2.20 ms 74.8 KiB
XMLSchema ONIX_BookProduct_3.1 quick_xml serialize 3.76 ms 4.20 ms 4.20 ms 4.76 ms 12.0 KiB
XMLSchema ONIX_BookProduct_3.1 quick_xml deserialize 22.42 ms 22.98 ms 23.03 ms 23.92 ms 125.9 KiB
XMLSchema (boxed) ONIX_BookProduct_3.1 quick_xml deserialize 19.05 ms 19.62 ms 19.58 ms 21.44 ms 68.8 KiB
XMLSchema XJustiz 3.4.1 (dabag) quick_xml serialize 1.23 ms 1.35 ms 1.35 ms 1.62 ms 56.0 KiB
XMLSchema XJustiz 3.4.1 (dabag) quick_xml deserialize 10.20 ms 10.49 ms 10.42 ms 12.62 ms 534.5 KiB
XMLSchema (boxed) XJustiz 3.4.1 (dabag) quick_xml deserialize 8.41 ms 8.59 ms 8.57 ms 8.94 ms 262.6 KiB
iDEAL 3.3.1 Merchant-Acquirer merchant-acquirer.xml quick_xml serialize 2.86 µs 3.21 µs 3.07 µs 9.96 µs 48 B
iDEAL 3.3.1 Merchant-Acquirer merchant-acquirer.xml serde (quick_xml) serialize 2.73 µs 3.42 µs 3.09 µs 9.80 µs 0 B
iDEAL 3.3.1 Merchant-Acquirer merchant-acquirer.xml serde (xml_rs) serialize 4.29 µs 4.55 µs 4.52 µs 5.84 µs 1.2 KiB
iDEAL 3.3.1 Merchant-Acquirer merchant-acquirer.xml quick_xml deserialize 15.88 µs 16.26 µs 16.02 µs 19.00 µs 15.8 KiB
iDEAL 3.3.1 Merchant-Acquirer (boxed) merchant-acquirer.xml quick_xml deserialize 13.02 µs 13.42 µs 13.20 µs 17.42 µs 11.8 KiB
iDEAL 3.3.1 Merchant-Acquirer merchant-acquirer.xml serde (quick_xml) deserialize 7.94 µs 8.71 µs 8.30 µs 15.59 µs 4.6 KiB
iDEAL 3.3.1 Merchant-Acquirer merchant-acquirer.xml serde (xml_rs v0.7) deserialize 38.09 µs 40.49 µs 39.84 µs 47.81 µs 9.7 KiB

The benchmarks were created on the following system: - OS: Linux (Ubuntu 24.04) - Kernel: Linux 6.8.0-88-generic - CPU Arch: x86_64 - CPU Brand: 12th Gen Intel(R) Core(TM) i9-12900H - CPU Vendor: GenuineIntel - CPU Cores (logical): 20 - CPU max Frequency: 4900.00 MHz

Changelog

Below you can find a short list of the most important changes for each released version.

Version 1.5.0

This release introduces several new schema features, a refactored identifier system, improved deserialization, and a range of bug fixes targeting real-world XSD compatibility.

  • Support for xs:anySimpleType xs:anySimpleType is now handled as a distinct type instead of being silently mapped to xs:string. A new AnySimpleType runtime type was added to xsd-parser-types, and the generator can be configured to use any custom type in its place.

  • Support for xs:redefine and xs:override The parser and interpreter now support the xs:redefine and xs:override schema composition mechanisms, enabling proper handling of schemas that redefine or override type definitions from imported schema files.

  • Namespace-Aware Enum Serialization and Deserialization Enum values that carry namespace-prefixed content (e.g., tns:Sender) are now correctly serialized and deserialized by resolving the namespace URI at runtime rather than comparing literal prefix strings. This fixes incorrect behavior for enums derived from xs:QName-like patterns.

  • Support for Duplicated Type Identifiers Across Schema Files The identifier system was restructured to distinguish between types from different schema files. The previous Ident type was split into TypeIdent, NodeIdent, and PropertyIdent. TypeIdent now carries a SchemaId, enabling correct resolution of types that share a name across multiple schema files.

  • DerivedTypeMeta for Naming Conflict Resolution A new DerivedTypeMeta structure tracks derived types and their display names within DynamicMeta. This resolves naming conflicts that occurred when multiple derived types shared the same name across different schemas (e.g., AIXM schema).

  • Support for Non-Zero Integer Types Integer types with matching XSD constraints can now be mapped to Rust's NonZero* types (e.g., NonZeroU8, NonZeroI32). This is independent of the WITH_NUM_BIG_INT feature and can be enabled via generator configuration.

  • Improved Name Generation The Naming trait and its built-in implementations were improved to handle more edge cases, including duplicate group names and nested types that previously caused naming collisions in generated code.

  • Anchored Regex Pattern Validation Pattern facets (xs:pattern) are now correctly anchored at the start and end (^...$) as required by the XSD specification. Additionally, patterns with alternation are wrapped in a non-capturing group to prevent partial anchoring issues.

  • Improved quick_xml Deserialization The quick_xml deserializer received a comprehensive overhaul, improving correctness for complex schema patterns such as dynamic types, mixed content, and deeply nested structures.

  • New Examples and Benchmarks

  • Added a BPMN 2.0 example project
  • Added a VSME schema example project
  • Added memory usage and performance benchmarks to the benchmark crate

  • Additional Bug Fixes

  • Fixed edge case in quick_xml deserialization of simple list types
  • Fixed namespace serialization for the Element type
  • Fixed list deserialization when using non-whitespace separators
  • Fixed invalid character escaping when deserializing XML attributes
  • Fixed naming collision for group types reused across inheritance hierarchies
  • Fixed WithNamespaceTrait generating conflicting implementations for type aliases
  • Fixed empty list handling (previously reported as an error)
  • Fixed a typo in the with_element_type_postfix setter method

Version 1.4.0

This release focuses on extending customization options, improving quick_xml serialization/deserialization, and restructuring the crate into a more modular form. It also includes numerous fixes for naming, type handling, and schema interpretation issues found in real-world XSDs.

  • Customizable Name Generation The entire naming system has been reworked to allow full customization of how identifiers are formatted and generated. This includes support for handling reserved keywords, resolving name collisions, and providing user-defined naming strategies.

  • Crate Split into xsd-parser and xsd-parser-types The library is now split into two crates. All runtime types and dependencies were moved into xsd-parser-types, reducing dependency overhead for users of the generator and improving compatibility with downstream projects.

  • Improved quick_xml Serializer/Deserializer The quick_xml backend received a comprehensive refactor. Namespace serialization has been improved, state naming is simplified, async reading tests were added, and multiple edge cases involving xs:any, xs:anyType, CDATA, mixed content, and boxed types are now handled correctly.

  • Extended Interpreter and Generator Capabilities Several comple

Extension points exported contracts — how you extend this code

NameFallback (Interface)
Helper trait used in [`NameBuilderExt::or`] and [`NameBuilderExt::or_else`] to define what can be used as fallback for a [13 …
xsd-parser/src/traits/naming.rs
WithDeserializer (Interface)
Trait that defines the [`Deserializer`] for a type. [619 implementers]
xsd-parser-types/src/quick_xml/deserialize.rs
AbstractTrait (Interface)
(no doc) [2 implementers]
xsd-parser/tests/optimizer/expected0/convert_dynamic_to_choice.rs
TypeEq (Interface)
Trait to check if two types are equal to each other or not. This trait will automatically resolve type definitions to i [23 …
xsd-parser/src/models/meta/type_eq.rs
Deserializer (Interface)
Trait that defines a deserializer that can be used to construct a type from a XML [`Event`]s. [619 implementers]
xsd-parser-types/src/quick_xml/deserialize.rs
BaseTrait (Interface)
(no doc) [2 implementers]
xsd-parser/tests/feature/nillable_dynamic_types/expected/quick_xml.rs
RenderStep (Interface)
Trait that is used to define a renderer. A render step is used to generate the actual code of a specific [`DataType`](c [12 …
xsd-parser/src/pipeline/renderer/mod.rs
DeserializeBytes (Interface)
Trait that could be implemented by types to support deserialization from XML byte streams using the [`quick_xml`] crate. [99 …
xsd-parser-types/src/quick_xml/deserialize.rs

Core symbols most depended-on inside this repo

is_none
called by 1416
xsd-parser/src/pipeline/renderer/steps/quick_xml/serialize.rs
is_some
called by 1299
xsd-parser/src/models/data/occurs.rs
init_start_tag_deserializer
called by 1244
xsd-parser-types/src/quick_xml/deserialize.rs
finish_element
called by 808
xsd-parser-types/src/quick_xml/deserialize.rs
default
called by 583
xsd-parser/src/misc/qname.rs
as_ref
called by 573
xsd-parser/src/models/name.rs
write_xmlns
called by 522
xsd-parser-types/src/quick_xml/serialize.rs
filter_xmlns_attributes
called by 483
xsd-parser-types/src/quick_xml/deserialize.rs

Shape

Class 4,151
Method 4,021
Enum 3,123
Function 778
Interface 48

Languages

Rust100%

Modules by API surface

xsd-parser/tests/schema/onix/expected/default.rs1,901 symbols
xsd-parser/tests/schema/factur_x/expected/en16931_quick_xml.rs594 symbols
xsd-parser/tests/schema/bmecat_etim_310/expected/quick_xml.rs578 symbols
xsd-parser/tests/schema/factur_x/expected/basic_quick_xml.rs478 symbols
xsd-parser/tests/schema/musicxml/expected/default.rs435 symbols
xsd-parser/tests/schema/factur_x/expected/basicwl_quick_xml.rs405 symbols
xsd-parser/tests/schema/xml_schema/expected/quick_xml.rs310 symbols
xsd-parser/tests/schema/xcb/expected/quick_xml.rs306 symbols
xsd-parser/src/models/schema/xs_generated.rs295 symbols
xsd-parser/tests/schema/ideal_merchant_acquirer/expected/quick_xml.rs277 symbols
xsd-parser/tests/schema/opendrive/v1_6/expected/default.rs201 symbols
xsd-parser/tests/schema/factur_x/expected/minimum_quick_xml.rs181 symbols

For agents

$ claude mcp add xsd-parser \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact