Xml.php
  1  <?php
  2  
  3  /**
  4   * Converts HTMLPurifier_ConfigSchema_Interchange to an XML format,
  5   * which can be further processed to generate documentation.
  6   */
  7  class HTMLPurifier_ConfigSchema_Builder_Xml extends XMLWriter
  8  {
  9  
 10      /**
 11       * @type HTMLPurifier_ConfigSchema_Interchange
 12       */
 13      protected $interchange;
 14  
 15      /**
 16       * @type string
 17       */
 18      private $namespace;
 19  
 20      /**
 21       * @param string $html
 22       */
 23      protected function writeHTMLDiv($html)
 24      {
 25          $this->startElement('div');
 26  
 27          $purifier = HTMLPurifier::getInstance();
 28          $html = $purifier->purify($html);
 29          $this->writeAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
 30          $this->writeRaw($html);
 31  
 32          $this->endElement(); // div
 33      }
 34  
 35      /**
 36       * @param mixed $var
 37       * @return string
 38       */
 39      protected function export($var)
 40      {
 41          if ($var === array()) {
 42              return 'array()';
 43          }
 44          return var_export($var, true);
 45      }
 46  
 47      /**
 48       * @param HTMLPurifier_ConfigSchema_Interchange $interchange
 49       */
 50      public function build($interchange)
 51      {
 52          // global access, only use as last resort
 53          $this->interchange = $interchange;
 54  
 55          $this->setIndent(true);
 56          $this->startDocument('1.0', 'UTF-8');
 57          $this->startElement('configdoc');
 58          $this->writeElement('title', $interchange->name);
 59  
 60          foreach ($interchange->directives as $directive) {
 61              $this->buildDirective($directive);
 62          }
 63  
 64          if ($this->namespace) {
 65              $this->endElement();
 66          } // namespace
 67  
 68          $this->endElement(); // configdoc
 69          $this->flush();
 70      }
 71  
 72      /**
 73       * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive
 74       */
 75      public function buildDirective($directive)
 76      {
 77          // Kludge, although I suppose having a notion of a "root namespace"
 78          // certainly makes things look nicer when documentation is built.
 79          // Depends on things being sorted.
 80          if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) {
 81              if ($this->namespace) {
 82                  $this->endElement();
 83              } // namespace
 84              $this->namespace = $directive->id->getRootNamespace();
 85              $this->startElement('namespace');
 86              $this->writeAttribute('id', $this->namespace);
 87              $this->writeElement('name', $this->namespace);
 88          }
 89  
 90          $this->startElement('directive');
 91          $this->writeAttribute('id', $directive->id->toString());
 92  
 93          $this->writeElement('name', $directive->id->getDirective());
 94  
 95          $this->startElement('aliases');
 96          foreach ($directive->aliases as $alias) {
 97              $this->writeElement('alias', $alias->toString());
 98          }
 99          $this->endElement(); // aliases
100  
101          $this->startElement('constraints');
102          if ($directive->version) {
103              $this->writeElement('version', $directive->version);
104          }
105          $this->startElement('type');
106          if ($directive->typeAllowsNull) {
107              $this->writeAttribute('allow-null', 'yes');
108          }
109          $this->text($directive->type);
110          $this->endElement(); // type
111          if ($directive->allowed) {
112              $this->startElement('allowed');
113              foreach ($directive->allowed as $value => $x) {
114                  $this->writeElement('value', $value);
115              }
116              $this->endElement(); // allowed
117          }
118          $this->writeElement('default', $this->export($directive->default));
119          $this->writeAttribute('xml:space', 'preserve');
120          if ($directive->external) {
121              $this->startElement('external');
122              foreach ($directive->external as $project) {
123                  $this->writeElement('project', $project);
124              }
125              $this->endElement();
126          }
127          $this->endElement(); // constraints
128  
129          if ($directive->deprecatedVersion) {
130              $this->startElement('deprecated');
131              $this->writeElement('version', $directive->deprecatedVersion);
132              $this->writeElement('use', $directive->deprecatedUse->toString());
133              $this->endElement(); // deprecated
134          }
135  
136          $this->startElement('description');
137          $this->writeHTMLDiv($directive->description);
138          $this->endElement(); // description
139  
140          $this->endElement(); // directive
141      }
142  }
143  
144  // vim: et sw=4 sts=4