diff --git a/src/Schema/Attribute/AbstractAttributeItem.php b/src/Schema/Attribute/AbstractAttributeItem.php index 98a7fd47..e3702a3f 100644 --- a/src/Schema/Attribute/AbstractAttributeItem.php +++ b/src/Schema/Attribute/AbstractAttributeItem.php @@ -5,6 +5,7 @@ namespace GoetasWebservices\XML\XSDReader\Schema\Attribute; use GoetasWebservices\XML\XSDReader\Schema\Item; +use GoetasWebservices\XML\XSDReader\Schema\MetaInformation; abstract class AbstractAttributeItem extends Item implements AttributeSingle { @@ -18,6 +19,11 @@ abstract class AbstractAttributeItem extends Item implements AttributeSingle protected string $use = self::USE_OPTIONAL; + /** + * @var list + */ + protected array $meta = []; + public function getFixed(): ?string { return $this->fixed; @@ -67,4 +73,20 @@ public function setUse(string $use): void { $this->use = $use; } + + /** + * @return list + */ + public function getMeta(): array + { + return $this->meta; + } + + /** + * @param list $meta + */ + public function setMeta(array $meta): void + { + $this->meta = $meta; + } } diff --git a/src/Schema/Attribute/AttributeSingle.php b/src/Schema/Attribute/AttributeSingle.php index 4f7114fa..88d51dd0 100644 --- a/src/Schema/Attribute/AttributeSingle.php +++ b/src/Schema/Attribute/AttributeSingle.php @@ -4,6 +4,7 @@ namespace GoetasWebservices\XML\XSDReader\Schema\Attribute; +use GoetasWebservices\XML\XSDReader\Schema\MetaInformation; use GoetasWebservices\XML\XSDReader\Schema\Type\Type; interface AttributeSingle extends AttributeItem @@ -35,4 +36,14 @@ public function setNil(bool $nil): void; public function getUse(): ?string; public function setUse(string $use): void; + + /** + * @param list $meta + */ + public function setMeta(array $meta): void; + + /** + * @return list + */ + public function getMeta(): array; } diff --git a/src/Schema/MetaInformation.php b/src/Schema/MetaInformation.php new file mode 100644 index 00000000..9b3ca9b2 --- /dev/null +++ b/src/Schema/MetaInformation.php @@ -0,0 +1,42 @@ +schema = $schema; + $this->name = $name; + $this->value = $value; + } + + public function getSchema(): Schema + { + return $this->schema; + } + + public function getName(): string + { + return $this->name; + } + + public function getValue(): string + { + return $this->value; + } +} diff --git a/src/SchemaReader.php b/src/SchemaReader.php index df0fd4bc..a3abb2a9 100644 --- a/src/SchemaReader.php +++ b/src/SchemaReader.php @@ -34,6 +34,7 @@ use GoetasWebservices\XML\XSDReader\Schema\Inheritance\Restriction; use GoetasWebservices\XML\XSDReader\Schema\Inheritance\RestrictionType; use GoetasWebservices\XML\XSDReader\Schema\Item; +use GoetasWebservices\XML\XSDReader\Schema\MetaInformation; use GoetasWebservices\XML\XSDReader\Schema\Schema; use GoetasWebservices\XML\XSDReader\Schema\SchemaItem; use GoetasWebservices\XML\XSDReader\Schema\Type\BaseComplexType; @@ -236,6 +237,27 @@ private function fillAttribute(AttributeSingle $attribute, \DOMElement $node): v if ($node->hasAttribute('use')) { $attribute->setUse($node->getAttribute('use')); } + + $attribute->setMeta($this->loadMetaAttributesForElement($attribute, $node)); + } + + /** + * @return list + */ + private function loadMetaAttributesForElement(SchemaItem $item, \DOMElement $node): array + { + $meta = []; + foreach ($node->attributes as $attr) { + if (null !== $attr->namespaceURI && self::XSD_NS !== $attr->namespaceURI) { + $meta[] = new MetaInformation( + $this->findSchemaForNamespace($item->getSchema(), $attr->namespaceURI), + $attr->name, + $attr->value + ); + } + } + + return $meta; } private function loadAttributeOrElementDef( @@ -1088,6 +1110,19 @@ private function findType(Schema $schema, \DOMElement $node, string $typeName): throw new TypeException(sprintf("Can't find %s named {%s}#%s, at line %d in %s ", 'type', $namespace, $name, $node->getLineNo(), $node->ownerDocument->documentURI)); } + public function findSchemaForNamespace(Schema $currentSchema, string $namespace): Schema + { + if ($currentSchema->getTargetNamespace() === $namespace) { + return $currentSchema; + } + + if (array_key_exists($namespace, $this->loadedSchemas) && count($this->loadedSchemas[$namespace]) > 0) { + return $this->loadedSchemas[$namespace][0]; + } + + throw new TypeException(sprintf("Can't find schema for namespace %s", $namespace)); + } + private function fillItem(Item $element, \DOMElement $node, ?\DOMElement $parentNode = null): void { if ($element instanceof ElementDef) { diff --git a/tests/AttributesTest.php b/tests/AttributesTest.php index ec1ec380..68b4f8de 100644 --- a/tests/AttributesTest.php +++ b/tests/AttributesTest.php @@ -144,4 +144,52 @@ public function testAttributeUseOverriding(): void self::assertEquals('language', $attribute->getType()->getName()); self::assertEquals(AttributeSingle::USE_REQUIRED, $attribute->getUse()); } + + public function testMetaInformation(): void + { + $schema = $this->reader->readString( + ' + + + ' + ); + + $myAttribute = $schema->findAttribute('myAttribute', 'http://www.example.com'); + self::assertInstanceOf(AttributeDef::class, $myAttribute); + + $meta = $myAttribute->getMeta(); + self::assertCount(1, $meta); + self::assertEquals('meta', $meta[0]->getName()); + self::assertEquals('hello', $meta[0]->getValue()); + self::assertSame($myAttribute->getSchema(), $meta[0]->getSchema()); + } + + public function testExternalSchemaReferencingMetaInformation(): void + { + $dom = new \DOMDocument(); + $dom->loadXML( + ' + + + + + + + + + + '); + $schema = $this->reader->readNodes(iterator_to_array($dom->documentElement->childNodes), 'file.xsd'); + + $myAttribute = $schema->findAttribute('myAttribute', 'http://www.example.com'); + self::assertInstanceOf(AttributeDef::class, $myAttribute); + + $meta = $myAttribute->getMeta(); + self::assertCount(1, $meta); + self::assertEquals('meta', $meta[0]->getName()); + self::assertEquals('hello', $meta[0]->getValue()); + + $refAttr = $schema->findAttribute('meta', 'http://www.ref.com'); + self::assertSame($refAttr->getSchema(), $meta[0]->getSchema()); + } }