diff --git a/src/Parser/Definitions/SchemaParser.php b/src/Parser/Definitions/SchemaParser.php index a571813..39a6c7e 100644 --- a/src/Parser/Definitions/SchemaParser.php +++ b/src/Parser/Definitions/SchemaParser.php @@ -74,9 +74,45 @@ private static function legacySchemaNodes(Document $wsdl): array $result[] = $node; } + self::importSiblingSchemas($result); + return $result; } + /** + * WSDLs often contain multiple inline schemas that reference each other without an explicit import. + * ext-soap treats all inline schemas as one pool of types, whereas the XSD reader only resolves + * references through imports. Adding the missing imports makes the inline schemas visible to each other. + * + * @param list $schemaNodes + */ + private static function importSiblingSchemas(array $schemaNodes): void + { + $namespaces = array_unique(array_filter( + array_map( + static fn (DOMElement $schema): string => $schema->getAttribute('targetNamespace'), + $schemaNodes + ) + )); + + foreach ($schemaNodes as $schema) { + $imported = [$schema->getAttribute('targetNamespace')]; + /** @var DOMNode $child */ + foreach ($schema->childNodes as $child) { + if ($child instanceof DOMElement && $child->namespaceURI === SchemaReader::XSD_NS && $child->localName === 'import') { + $imported[] = $child->getAttribute('namespace'); + } + } + + foreach (array_diff($namespaces, $imported) as $namespace) { + $import = $schema->ownerDocument->createElementNS(SchemaReader::XSD_NS, 'import'); + assert($import instanceof DOMElement); + $import->setAttribute('namespace', $namespace); + $schema->insertBefore($import, $schema->firstChild); + } + } + } + /** * TODO: Can be removed once goetas-webservices/xsd-reader supports Dom\Element. */ diff --git a/tests/PhpCompatibility/schema1017.phpt b/tests/PhpCompatibility/schema1017.phpt new file mode 100644 index 0000000..091487e --- /dev/null +++ b/tests/PhpCompatibility/schema1017.phpt @@ -0,0 +1,34 @@ +--TEST-- +SOAP XML Schema 1017: Inline schemas referencing each other without explicit imports +--FILE-- + + + + + + + + + + + + + +EOF; +test_schema($schema,'type="tns:testType"'); +?> +--EXPECT-- +Methods: + > test(testType $testParam): void + +Types: + > http://test-uri/:testType { + Selection $selection + } + > http://test-uri/:Vehicle extends anySimpleType + > http://test-uri/other/:Selection { + string $Vehicle + }