diff --git a/src/SchemaReader.php b/src/SchemaReader.php index 5ba851d6..8b742854 100644 --- a/src/SchemaReader.php +++ b/src/SchemaReader.php @@ -3,6 +3,7 @@ use DOMDocument; use DOMElement; +use DOMNode; use GoetasWebservices\XML\XSDReader\Exception\IOException; use GoetasWebservices\XML\XSDReader\Exception\TypeException; use GoetasWebservices\XML\XSDReader\Schema\Attribute\Attribute; @@ -649,6 +650,11 @@ private function loadImport(Schema $schema, DOMElement $node) $schema->addSchema($this->loadedFiles[self::$globalSchemaInfo[$node->getAttribute("namespace")]]); + return function () { + }; + } elseif ($node->hasAttribute("namespace") + && isset($this->loadedFiles[$this->getNamespaceSpecificFileIndex($file, $node->getAttribute("namespace"))])) { + $schema->addSchema($this->loadedFiles[$this->getNamespaceSpecificFileIndex($file, $node->getAttribute("namespace"))]); return function () { }; } elseif (isset($this->loadedFiles[$file])) { @@ -684,7 +690,7 @@ private function loadImport(Schema $schema, DOMElement $node) /** * - * @return \GoetasWebservices\XML\XSDReader\Schema\Schema + * @return Schema */ public function getGlobalSchema() { @@ -714,11 +720,15 @@ public function getGlobalSchema() } /** - * @return \GoetasWebservices\XML\XSDReader\Schema\Schema + * @param DOMNode $node + * @param string $file + * + * @return Schema */ - public function readNode(\DOMNode $node, $file = 'schema.xsd') + public function readNode(DOMNode $node, $file = 'schema.xsd') { - $this->loadedFiles[$file] = $rootSchema = new Schema(); + $fileKey = $node instanceof DOMElement && $node->hasAttribute('targetNamespace') ? $this->getNamespaceSpecificFileIndex($file, $node->getAttribute('targetNamespace')) : $file; + $this->loadedFiles[$fileKey] = $rootSchema = new Schema(); $rootSchema->addSchema($this->getGlobalSchema()); $callbacks = $this->schemaNode($rootSchema, $node); @@ -730,9 +740,29 @@ public function readNode(\DOMNode $node, $file = 'schema.xsd') return $rootSchema; } + /** + * It is possible that a single file contains multiple nodes, for instance in a WSDL file. + * + * Each of these nodes typically target a specific namespace. Append the target namespace to the + * file to distinguish between multiple schemas in a single file. + * + * @param string $file + * @param string $targetNamespace + * + * @return string + */ + private function getNamespaceSpecificFileIndex($file, $targetNamespace) + { + return $file . '#' . $targetNamespace; + } /** - * @return \GoetasWebservices\XML\XSDReader\Schema\Schema + * @param string $content + * @param string $file + * + * @return Schema + * + * @throws IOException */ public function readString($content, $file = 'schema.xsd') { @@ -746,7 +776,9 @@ public function readString($content, $file = 'schema.xsd') } /** - * @return \GoetasWebservices\XML\XSDReader\Schema\Schema + * @param string $file + * + * @return Schema */ public function readFile($file) { @@ -756,8 +788,10 @@ public function readFile($file) /** * @param string $file + * + * @return DOMDocument + * * @throws IOException - * @return \DOMDocument */ private function getDOM($file) { diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index 7340b417..62c26c22 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -69,4 +69,43 @@ public function testBase() $this->assertInstanceOf('GoetasWebservices\XML\XSDReader\Schema\Attribute\AttributeDef', $schema->findAttribute('myAttribute', 'http://www.example.com')); } + + public function testMultipleSchemasInSameFile() + { + $file = 'schema.xsd'; + $schema1 = $this->reader->readString(' + + + + + + + + + + ', + $file + ); + + $this->assertCount(1, $schema1->getTypes()); + $this->assertInstanceOf('GoetasWebservices\XML\XSDReader\Schema\Type\ComplexType', $schema1->findType('myType', 'http://www.example.com')); + + $this->assertCount(1, $schema1->getElements()); + $this->assertInstanceOf('GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef', $schema1->findElement('myElement', 'http://www.example.com')); + + //Now use a second schema which imports from the first one, and is in the SAME file + $schema2 = $this->reader->readString(' + + + + ', + $file + ); + + $this->assertCount(0, $schema2->getTypes()); + + $this->assertCount(1, $schema2->getElements()); + $this->assertInstanceOf('GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef', $schema2->findElement('myElement2', 'http://www.example2.com')); + + } } \ No newline at end of file