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 @@
+
+
+
+
+
+