Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Kacper Stasik committed Mar 3, 2017
1 parent 91f838b commit 1ccae4d
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
42 changes: 40 additions & 2 deletions src/SchemaReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ private function schemaNode(Schema $schema, DOMElement $node, Schema $parent = n
case 'import':
$functions[] = $this->loadImport($schema, $childNode);
break;
case 'redefine':
$functions[] = $this->loadRedefine($schema, $childNode);
break;
case 'element':
$functions[] = $this->loadElementDef($schema, $childNode);
break;
Expand Down Expand Up @@ -204,7 +207,7 @@ private function loadElement(Schema $schema, DOMElement $node)

$xp = new \DOMXPath($node->ownerDocument);
$xp->registerNamespace('xs', 'http://www.w3.org/2001/XMLSchema');

if ($xp->query('ancestor::xs:choice', $node)->length) {
$element->setMin(0);
}
Expand Down Expand Up @@ -639,6 +642,41 @@ private function fillItem(Item $element, DOMElement $node)
}
}

private function loadRedefine(Schema $schema, DOMElement $node)
{
$base = urldecode($node->ownerDocument->documentURI);
$file = UrlUtils::resolveRelativeUrl($base, $node->getAttribute("schemaLocation"));

if (isset($this->loadedFiles[$file])) {
/* @var $redefined Schema */
$redefined = clone $this->loadedFiles[$file];

if($schema->getTargetNamespace() != $redefined->getTargetNamespace()){
$redefined->setTargetNamespace($schema->getTargetNamespace());
}

$schema->addSchema($redefined);

$callbacks = $this->schemaNode($redefined, $node, $schema);
}
else{
$redefined = new Schema();
$redefined->addSchema($this->getGlobalSchema());

$xml = $this->getDOM(isset($this->knownLocationSchemas[$file]) ? $this->knownLocationSchemas[$file] : $file);

$callbacks = $this->schemaNode($redefined, $xml->documentElement, $schema);

$schema->addSchema($redefined);
}

return function () use ($callbacks) {
foreach ($callbacks as $callback) {
call_user_func($callback);
}
};
}

private function loadImport(Schema $schema, DOMElement $node)
{
$base = urldecode($node->ownerDocument->documentURI);
Expand Down Expand Up @@ -722,7 +760,7 @@ public function getGlobalSchema()
/**
* @param DOMNode $node
* @param string $file
*
*
* @return Schema
*/
public function readNode(DOMNode $node, $file = 'schema.xsd')
Expand Down
66 changes: 66 additions & 0 deletions tests/RedefineTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
namespace GoetasWebservices\XML\XSDReader\Tests;

class RedefineTest extends BaseTest
{
public function testBase()
{
$remoteSchema = $this->reader->readString(
'
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="personName">
<xs:sequence>
<xs:element name="title" minOccurs="0"/>
<xs:element name="forename" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="addressee" type="personName"/>
</xs:schema>', 'http://www.example.com/xsd.xsd');


$schema = $this->reader->readString(
'
<xs:schema targetNamespace="http://www.user.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ex="http://www.example.com">
<xs:redefine schemaLocation="http://www.example.com/xsd.xsd">
<xs:complexType name="personName">
<xs:complexContent>
<xs:extension base="personName">
<xs:sequence>
<xs:element name="generation" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
<xs:element name="author" type="personName"/>
</xs:schema>');

// check if schema is not included
// we don't want to redefine original schema
$this->assertNotContains($remoteSchema, $schema->getSchemas(), '', true);

/* @var $localAttr \GoetasWebservices\XML\XSDReader\Schema\Element\ElementDef */

// it should inherit namespace of main schema
$localAttr = $schema->findElement("addressee", "http://www.user.com");
$this->assertNotNull($localAttr);

// find author element
$localAttr = $schema->findElement("author", "http://www.user.com");
$this->assertNotNull($localAttr);

/* @var $type \GoetasWebservices\XML\XSDReader\Schema\Type\ComplexType */
$type = $localAttr->getType();

$this->assertInstanceOf('\GoetasWebservices\XML\XSDReader\Schema\Type\ComplexType', $type);

$children = array();
foreach($type->getElements() as $element){
$children[] = $element->getName();
}

$this->assertContains('generation', $children);
}
}

0 comments on commit 1ccae4d

Please sign in to comment.