diff --git a/src/Xml/Configurator/FlattenXsdImports.php b/src/Xml/Configurator/FlattenXsdImports.php index af52a5d..ee371d0 100644 --- a/src/Xml/Configurator/FlattenXsdImports.php +++ b/src/Xml/Configurator/FlattenXsdImports.php @@ -18,11 +18,13 @@ use VeeWee\Xml\Exception\RuntimeException; use function Psl\Type\instance_of; use function Psl\Type\nullable; +use function Psl\Vec\reverse; use function VeeWee\Xml\Dom\Assert\assert_element; use function VeeWee\Xml\Dom\Locator\Node\children; use function VeeWee\Xml\Dom\Manipulator\Element\copy_named_xmlns_attributes; use function VeeWee\Xml\Dom\Manipulator\Node\append_external_node; use function VeeWee\Xml\Dom\Manipulator\Node\remove; +use function VeeWee\Xml\Dom\Xpath\Configurator\functions; /** * This class deals with xsd:import, xsd:include and xsd:redefine tags. @@ -65,6 +67,8 @@ public function __invoke(DOMDocument $document): DOMDocument } } + $this->rearrangeImportsAsFirstElements($xml); + return $document; } @@ -219,4 +223,31 @@ private function fixRemovedDefaultXmlnsDeclarationsDuringImport(DOMElement $targ $target->setAttribute('xmlns', $source->getAttribute('xmlns')); } + + /** + * Makes sure to rearrange the import statements on top of the flattened XSD schema. + * This makes the flattened XSD spec compliant: + * + * @see https://www.w3.org/TR/xmlschema11-1/#declare-schema + * + * + * Content: ((include | import | redefine | override | annotation)*, + * (defaultOpenContent, annotation*)?, + * ((simpleType | complexType | group | attributeGroup | element | attribute | notation), annotation*)*) + * + * + * @throws RuntimeException + */ + private function rearrangeImportsAsFirstElements(Document $xml): void + { + $xpath = $xml->xpath(new WsdlPreset($xml), functions(['array_reverse'])); + $imports = $xpath + ->query('//schema:import') + ->expectAllOfType(DOMElement::class); + + foreach (reverse($imports) as $import) { + $parentSchema = assert_element($import->parentNode); + $parentSchema->prepend($import); + } + } } diff --git a/tests/Unit/Xml/Configurator/FlattenXsdImportsTest.php b/tests/Unit/Xml/Configurator/FlattenXsdImportsTest.php index bbbec67..fe06559 100644 --- a/tests/Unit/Xml/Configurator/FlattenXsdImportsTest.php +++ b/tests/Unit/Xml/Configurator/FlattenXsdImportsTest.php @@ -71,5 +71,10 @@ public function provideTestCases() 'expected' => Document::fromXmlFile(FIXTURE_DIR.'/flattening/result/root-xmlns-import-issue-result.wsdl'), canonicalize(), ]; + yield 'rearranged-imports' => [ + 'wsdl' => FIXTURE_DIR.'/flattening/rearranged-imports.wsdl', + 'expected' => Document::fromXmlFile(FIXTURE_DIR.'/flattening/result/rearranged-imports.wsdl'), + comparable(), + ]; } } diff --git a/tests/fixtures/flattening/rearranged-imports.wsdl b/tests/fixtures/flattening/rearranged-imports.wsdl new file mode 100644 index 0000000..fea0739 --- /dev/null +++ b/tests/fixtures/flattening/rearranged-imports.wsdl @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/tests/fixtures/flattening/result/rearranged-imports.wsdl b/tests/fixtures/flattening/result/rearranged-imports.wsdl new file mode 100644 index 0000000..f2d83bc --- /dev/null +++ b/tests/fixtures/flattening/result/rearranged-imports.wsdl @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/tests/fixtures/flattening/xsd/rearranged-import.xsd b/tests/fixtures/flattening/xsd/rearranged-import.xsd new file mode 100644 index 0000000..2c9b07c --- /dev/null +++ b/tests/fixtures/flattening/xsd/rearranged-import.xsd @@ -0,0 +1 @@ + diff --git a/tests/fixtures/flattening/xsd/rearranged-import1.xsd b/tests/fixtures/flattening/xsd/rearranged-import1.xsd new file mode 100644 index 0000000..a2559dd --- /dev/null +++ b/tests/fixtures/flattening/xsd/rearranged-import1.xsd @@ -0,0 +1 @@ + diff --git a/tests/fixtures/flattening/xsd/rearranged-import2.xsd b/tests/fixtures/flattening/xsd/rearranged-import2.xsd new file mode 100644 index 0000000..eb609d0 --- /dev/null +++ b/tests/fixtures/flattening/xsd/rearranged-import2.xsd @@ -0,0 +1 @@ + diff --git a/tests/fixtures/flattening/xsd/rearranged-include1.xsd b/tests/fixtures/flattening/xsd/rearranged-include1.xsd new file mode 100644 index 0000000..acfbdd6 --- /dev/null +++ b/tests/fixtures/flattening/xsd/rearranged-include1.xsd @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/fixtures/flattening/xsd/rearranged-include2.xsd b/tests/fixtures/flattening/xsd/rearranged-include2.xsd new file mode 100644 index 0000000..4f61863 --- /dev/null +++ b/tests/fixtures/flattening/xsd/rearranged-include2.xsd @@ -0,0 +1,6 @@ + + + + + +