function visitElementNode(PiBX_ParseTree_Tree $tree) { $this->plowTypesForLevel($tree->getLevel()); $logMessage = $tree->getLevel() . str_pad(" ", $tree->getLevel()) . " element"; if ($tree->isAnonym()) { $logMessage .= " <anonym>"; } else { $logMessage .= " (" . $tree->getName() . ")"; } if ($tree->getLevel() > 0) { if ($this->currentType() instanceof PiBX_AST_Type) { $ta = new PiBX_AST_TypeAttribute($tree->getName()); $ta->setType($tree->getType()); $schemaType = $tree->getType(); $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $ta); array_push($this->stack, $sf); // elements with maxOccurs "unbounded" are collections/lists // with no parent collection element. if ($tree->getMaxOccurs() == 'unbounded') { $ci = new PiBX_AST_CollectionItem($tree->getName()); $ci->setType($tree->getType()); $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $ci); array_push($this->stack, $sf); } } elseif ($this->currentType() instanceof PiBX_AST_Collection) { $ci = new PiBX_AST_CollectionItem($tree->getName()); $ci->setType($tree->getType()); $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $ci); array_push($this->stack, $sf); } elseif ($this->currentType() instanceof PiBX_AST_Structure) { $se = new PiBX_AST_StructureElement($tree->getName(), $tree->getType()); $sf = new PiBX_CodeGen_ASTStackFrame($tree->getLevel(), $se); array_push($this->stack, $sf); } } elseif ($tree->getLevel() == 0) { $logMessage .= " - global"; $t = new PiBX_AST_Type($tree->getName()); if ($this->countTypes() == 0) { // the first type is the XSD-root. $t->setAsRoot(); $t->setTargetNamespace($tree->getParent()->getTargetNamespace()); $t->setNamespaces($tree->getNamespaces()); } $sf = new PiBX_CodeGen_ASTStackFrame(-1, $t); array_push($this->stack, $sf); /* * Yes, add it two times. * It's a limitation that exist in the current implementation * of the TypeUsage-class. * The concrete class (which is the root element/type of a schema) * will not be referenced more than one time (at the definition). * But it must not be removed in an AST optimization afterwards, * so we just increase the usage-counter by one. */ $this->typeUsage->addType($tree->getName()); $this->typeUsage->addType($tree->getName()); } else { throw new RuntimeException('invalid element state'); } $this->lastLevel = $tree->getLevel(); $this->log($logMessage); }
public function testComplexTypeWithElementsAndSequence() { $data = <<<XML <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:complexType name="complexTypeWithElements"> <xs:sequence> <xs:element name="element1" type="xs:string"/> <xs:element name="element2" type="xs:long"/> <xs:element name="element3" type="xs:string"/> <xs:element name="element4" type="xs:string" minOccurs="0"/> <xs:element name="elements" > <xs:complexType> <xs:sequence> <xs:element name="element" type="xs:string" minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="element6" type="xs:date"/> </xs:sequence> </xs:complexType> </xs:schema> XML; $expectedType = new PiBX_AST_Type('complexTypeWithElements'); $expectedType->setAsRoot(); $expectedType->setAttributeCount(6); $expectedType->setNamespaces(array('xs' => 'http://www.w3.org/2001/XMLSchema')); $attr = new PiBX_AST_TypeAttribute('element1'); $attr->setType('string'); $expectedType->add($attr); $attr = new PiBX_AST_TypeAttribute('element2'); $attr->setType('long'); $expectedType->add($attr); $attr = new PiBX_AST_TypeAttribute('element3'); $attr->setType('string'); $expectedType->add($attr); $attr = new PiBX_AST_TypeAttribute('element4'); $attr->setType('string'); $expectedType->add($attr); $attr = new PiBX_AST_TypeAttribute('elements'); $collection = new PiBX_AST_Collection(''); $collectionItem = new PiBX_AST_CollectionItem('element'); $collectionItem->setType('string'); $collection->add($collectionItem); $attr->add($collection); $expectedType->add($attr); $attr = new PiBX_AST_TypeAttribute('element6'); $attr->setType('date'); $expectedType->add($attr); $schema = simplexml_load_string($data); $parser = new PiBX_CodeGen_SchemaParser(); $parser->setSchema($schema); $tree = $parser->parse(); $creator = new PiBX_CodeGen_ASTCreator(new PiBX_CodeGen_TypeUsage()); $tree->accept($creator); $typeList = $creator->getTypeList(); list($type) = $typeList; $this->assertEquals($expectedType, $type); }