Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Xsd Reader Laravel Package

goetas-webservices/xsd-reader

Reads XML Schema (XSD) documents into a clean PHP object model, handling includes, imports, simple and complex types, and namespaces. A lightweight foundation for WSDL readers, SOAP clients, and code generators.

Deep Wiki
Context7

Getting Started

Install the reader and confirm the DOM extension is available:

composer require goetas-webservices/xsd-reader

The first entry point is GoetasWebservices\Xml\XsdReader\SchemaReader. Load a file with readFile() when the schema has relative imports/includes, because the reader can resolve them relative to the document location:

use GoetasWebservices\Xml\XsdReader\SchemaReader;

$reader = new SchemaReader();
$schema = $reader->readFile(__DIR__ . '/xsd/order.xsd');

printf("Target namespace: %s\n", $schema->getTargetNamespace());

foreach ($schema->getElements() as $element) {
    printf(
        "element %s : %s\n",
        $element->getName(),
        $element->getType()?->getName() ?? 'anonymous/inline'
    );
}

Look first at these classes:

  • SchemaReader — file/string loading and import resolution.
  • Schema\Schema — target namespace, root elements, types, attributes, groups.
  • Schema\Type\ComplexType / Schema\Type\SimpleType — type structure.
  • Schema\Element\Element and Schema\Attribute\Attribute — declarations and references.

A good first use case is schema inventory: point the reader at a vendor XSD, list root elements and types, and confirm namespaces and imports resolve as expected. Once that works, feed the same Schema objects into goetas-webservices/xsd2php for PHP class generation or into wsdl-reader for SOAP/WSDL tooling.

Implementation Patterns

Namespace-aware lookup, not name-only lookup. XSDs routinely have the same local name in different namespaces. Use Clark-notation keys such as {urn:example}OrderType for your own maps, and pass the namespace explicitly when using finder methods:

$element = $schema->findElement('PurchaseOrder', 'urn:example:orders');
$type    = $element?->getType();

$key = '{' . $type->getSchema()->getTargetNamespace() . '}' . $type->getName();

If finder methods return null, fall back to iterating getTypes()/getElements() and comparing both namespace and local name.

Build a type registry once per request. For code generation, validation metadata, or hydration maps, walk the schema graph and build a stable registry instead of repeatedly searching:

$types = [];

foreach ($schema->getTypes() as $type) {
    $ns  = $type->getSchema()->getTargetNamespace() ?? '';
    $key = '{' . $ns . '}' . $type->getName();
    $types[$key] = $type;
}

For each ComplexType, inspect getElements(), getAttributes(), and group/attribute-group references. For SimpleType, inspect restriction/list/union structure. Preserve the base type when following getExtension() or getRestriction() so generators can model inheritance instead of flattening everything.

Use the companion ecosystem rather than rebuilding generators. This package is a reader, not a code generator or validator. The highest-leverage workflow is:

  1. Read XSDs with SchemaReader.
  2. Use xsd2php to convert the object model into PHP classes and serialization metadata.
  3. Use wsdl-reader when the real input is a WSDL and you only need schema-level introspection for parts.

This keeps your application code focused on consuming generated classes, while the reader handles imports, includes, namespaces, and type traversal.

Mirror remote schemas locally before parsing. Vendor XSDs often import from HTTP URLs. In CI and production, download the schema tree once into a directory, preserve relative paths, and call readFile() against the local copy. This avoids network dependencies during builds and makes import failures reproducible.

Normalize before generation. Anonymous inline complex types are common. If you are producing class names or metadata keys, assign synthetic stable names based on the parent element/type path. Do the normalization after reading, not by string-editing the XSD, so the reader’s namespace resolution stays intact.

Use extension callbacks for custom schema handling. The reader advertises extensible callbacks for custom schema handling. Use them for narrow concerns: rewriting a vendor schemaLocation, mapping a remote namespace to a local file, or post-processing a schema before traversal. Keep callbacks deterministic and side-effect free; they are easy to make global accidentally.

Cache the extracted metadata, not the object graph. The Schema objects are convenient to traverse but are tied to parsed XML state. Cache a plain array/JSON representation of what you need—element names, type names, namespaces, base types, cardinalities—or cache generated PHP files. Re-reading a small XSD is usually cheaper and safer than trying to serialize the object model.

Gotchas and Tips

  • readString() loses the base path. Relative import/include locations cannot be resolved reliably from an in-memory string. Prefer readFile(), or rewrite all schemaLocation values to absolute paths before calling readString().
  • Chameleon includes are a real edge case. An included schema with no targetNamespace inherits the includer’s namespace. Do not cache solely by target namespace; include the schema location in your cache key.
  • Canonicalize paths for cycle handling. Imports can form cycles or include the same file through different relative paths. Use realpath() or a canonical URI as the cache key when you build your own schema registry.
  • Unqualified local elements and attributes are easy to mis-key. elementFormDefault and attributeFormDefault affect whether local declarations are in the target namespace. If you write custom traversal code, check qualification rather than assuming every name is namespace-qualified.
  • getType() can be null or unresolved. Handle references, inline anonymous types, and unresolved external types defensively. A null type should produce a clear diagnostic with the element name and namespace, not a fatal error deep in a generator.
  • This is not an instance validator. It parses schema documents into an object model. To validate an actual XML instance, use DOMDocument::schemaValidate() or a dedicated validator.
  • Treat untrusted XSDs as untrusted XML. External entity resolution and remote imports can become SSRF/XXE risks. Parse vendor schemas in a controlled environment, disable network access where possible, and avoid feeding user-supplied XSDs into a privileged process without sandboxing.
  • Wrap parse errors with context. Catch reader exceptions and rethrow with the file path, namespace, and import chain. “Could not read schema” is not actionable when a deeply nested include is the real failure.
  • Debug with tiny fixtures. When a large vendor schema fails, reproduce with a three-file fixture: root schema, imported schema, and included schema. Dump getTargetNamespace() and the class names returned by getTypes() before debugging generation logic.
  • Pin the version and test upgrades. The package is stable but the API surface is an object model; minor releases can change traversal details. Pin in composer.json and run your schema fixtures in CI.
  • Do not over-model groups initially. group and attributeGroup references can be expanded during generation or preserved as structures. Pick one strategy early; mixing both usually produces duplicate or missing properties.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk