Skip to content

Commit

Permalink
Support for XML Schema’s with different target namespaces in the same…
Browse files Browse the repository at this point in the history
… file (possible in WSDL files)
  • Loading branch information
holtkamp committed Feb 17, 2017
1 parent 220b0d7 commit 9d702be
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 7 deletions.
48 changes: 41 additions & 7 deletions src/SchemaReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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])) {
Expand Down Expand Up @@ -684,7 +690,7 @@ private function loadImport(Schema $schema, DOMElement $node)

/**
*
* @return \GoetasWebservices\XML\XSDReader\Schema\Schema
* @return Schema
*/
public function getGlobalSchema()
{
Expand Down Expand Up @@ -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);
Expand All @@ -730,9 +740,29 @@ public function readNode(\DOMNode $node, $file = 'schema.xsd')
return $rootSchema;
}

/**
* It is possible that a single file contains multiple <xsd:schema/> nodes, for instance in a WSDL file.
*
* Each of these <xsd:schema/> 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')
{
Expand All @@ -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)
{
Expand All @@ -756,8 +788,10 @@ public function readFile($file)

/**
* @param string $file
*
* @return DOMDocument
*
* @throws IOException
* @return \DOMDocument
*/
private function getDOM($file)
{
Expand Down
39 changes: 39 additions & 0 deletions tests/SchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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('
<xs:schema targetNamespace="http://www.example.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="myType"></xs:complexType>
<xs:element name="myElement" type="myType"></xs:element>
<xs:group name="myGroup">
<xs:sequence></xs:sequence>
</xs:group>
<xs:attribute name="myAttribute" type="xs:string"></xs:attribute>
<xs:attributeGroup name="myAttributeGroup"></xs:attributeGroup>
</xs:schema>',
$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('
<xs:schema targetNamespace="http://www.example2.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://www.example.com">
<xs:import namespace="http://www.example.com"/>
<xs:element name="myElement2" type="ns1:myType"></xs:element>
</xs:schema>',
$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'));

}
}

0 comments on commit 9d702be

Please sign in to comment.