/** * Visit a schema * * The visitor is not structured, since the types might be required to be * iterated tree-based for more complex schema definitions (like XML Schema * schemas). * * The return value depends on the concrete visitor implementation. * * @param slSchema $schema * @return string */ public function visit(slSchema $schema) { $rootElements = $schema->getRootElements(); if (count($rootElements) > 1) { // @todo: Use a proper exception here throw new RuntimeException('Invalid DTD schema: Too many root elements.'); } $root = reset($rootElements); $dtd = ''; // Visit all elements / types foreach ($schema->getTypes() as $element) { $dtd .= $this->visitElement($element); } $dtd .= "\n"; // Visit all attributes below the element definitions $regExpVisitor = new slRegularExpressionDtdVisitor(); foreach ($schema->getTypes() as $element) { foreach ($element->type->attributes as $attribute) { $dtd .= $this->visitAttribute($element, $attribute); } } return trim($dtd) . "\n"; }
/** * Visit a schema * * The visitor is not structured, since the types might be required to be * iterated tree-based for more complex schema definitions (like XML Schema * schemas). * * The return value depends on the concrete visitor implementation. * * @param slSchema $schema * @return string */ public function visit(slSchema $schema) { $doc = new DOMDocument(); $doc->formatOutput = true; $root = $doc->createElementNS('http://www.w3.org/2001/XMLSchema', 'schema'); $root->setAttribute('targetNamespace', 'http://example.com/generated'); $root->setAttribute('elementFormDefault', 'qualified'); $doc->appendChild($root); $rootElements = $schema->getRootElements(); $visitedTypes = array(); foreach ($this->types = $schema->getTypes() as $type) { if ($elementName = array_search($type->type, $rootElements)) { $element = $doc->createElementNS('http://www.w3.org/2001/XMLSchema', 'element'); $element->setAttribute('name', $elementName); $element->setAttribute('type', $type->type); $root->appendChild($element); } if (!isset($visitedTypes[$type->type->name])) { $this->visitType($root, $type); $visitedTypes[$type->type->name] = true; } } return $doc->saveXml(); }
/** * Build type graph * * Builds a type graph from the schema type definitions and child patterns * associated with the types. * * The type grapg represents a (information science) graph where each edge * indicates that the dst type occurs within the src type. * * @param slSchema $schema * @return slTypeAutomaton */ protected function buildTypeGraph(slSchema $schema) { $automaton = new slTypeAutomaton(); // Add edges for root nodes foreach ($schema->getRootElements() as $root) { $automaton->addEdge('_start', $root, $root); } // Get contained children from each type and add edges for them to the // graph foreach ($schema->getTypes() as $element) { foreach ($this->getChildElements($element->type->regularExpression) as $child) { $automaton->addEdge($element->type->name, $child->type, $child->name); } } return $automaton; }