Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/Parser/Definitions/SchemaParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<DOMElement> $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.
*/
Expand Down
34 changes: 34 additions & 0 deletions tests/PhpCompatibility/schema1017.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
--TEST--
SOAP XML Schema 1017: Inline schemas referencing each other without explicit imports
--FILE--
<?php
include __DIR__."/test_schema.inc";
$schema = <<<EOF
<element name="Vehicle" type="string"/>
<complexType name="testType" xmlns:other="http://test-uri/other/">
<sequence>
<element name="selection" type="other:Selection"/>
</sequence>
</complexType>
</schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://test-uri/" targetNamespace="http://test-uri/other/">
<complexType name="Selection">
<sequence>
<element ref="ns1:Vehicle"/>
</sequence>
</complexType>
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
}
Loading