Added XMLWriter as wrapper for PHP's build-in XMLWriter
authorAlexander Ebert <ebert@woltlab.com>
Sat, 13 Oct 2012 18:26:34 +0000 (20:26 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 13 Oct 2012 18:26:34 +0000 (20:26 +0200)
wcfsetup/install/files/lib/util/XMLWriter.class.php [new file with mode: 0644]

diff --git a/wcfsetup/install/files/lib/util/XMLWriter.class.php b/wcfsetup/install/files/lib/util/XMLWriter.class.php
new file mode 100644 (file)
index 0000000..ef7da2f
--- /dev/null
@@ -0,0 +1,158 @@
+<?php
+namespace wcf\util;
+use wcf\system\exception\SystemException;
+
+/**
+ * Writes XML documents.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2012 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage util
+ * @category   Community Framework
+ */
+class XMLWriter {
+       /**
+        * true, if a document is still processed
+        * @var boolean
+        */
+       protected $activeDocument = false;
+       
+       /**
+        * number of open elments
+        * @var integer
+        */
+       protected $openElements = 0;
+       
+       /**
+        * XMLWriter object
+        * @var \XMLWriter
+        */
+       protected $xml = null;
+       
+       /**
+        * Creates a new XML document.
+        * 
+        * @param       string          $rootElement
+        * @param       string          $namespace
+        * @param       string          $schemaLocation
+        * @param       array<string>   $attributes
+        */
+       public function beginDocument($rootElement, $namespace, $schemaLocation, array $attributes = array()) {
+               if ($this->activeDocument) {
+                       throw new SystemException("Could not begin a new document unless the previous is finished");
+               }
+               
+               if ($this->xml === null) {
+                       $this->xml = new \XMLWriter();
+                       $this->xml->openMemory();
+                       $this->xml->setIndent(true);
+                       $this->xml->setIndentString("\t");
+               }
+               
+               $this->xml->startDocument('1.0', 'UTF-8');
+               $this->startElement($rootElement);
+               $attributes = array_merge($attributes, array(
+                       'xmlns' => $namespace,
+                       'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+                       'xsi:schemaLocation' => $namespace . ' ' . $schemaLocation
+               ));
+               $this->writeAttributes($attributes);
+               
+               $this->activeDocument = true;
+       }
+       
+       /**
+        * Returns the generated XML document or writes it to given filename. All open
+        * elements will be automatically closed before flushing.
+        * 
+        * @param       string          $filename
+        * @return      mixed
+        */
+       public function endDocument($filename = '') {
+               // mark document as done
+               $this->activeDocument = false;
+               
+               // close all open tags
+               while ($this->openElements) {
+                       $this->endElement();
+               }
+               
+               if (empty($filename)) {
+                       // return XML as string
+                       return $this->xml->flush(true);
+               }
+               else {
+                       // write to file
+                       file_put_contents($filename, $this->xml->flush(true));
+               }
+       }
+       
+       /**
+        * Begins a new element.
+        * 
+        * @param       string          $element
+        * @param       array<string>   $attributes
+        */
+       public function startElement($element, array $attributes = array()) {
+               $this->xml->startElement($element);
+               $this->openElements++;
+               
+               if (!empty($attributes)) {
+                       $this->writeAttributes($attributes);
+               }
+       }
+       
+       /**
+        * Ends the last opened element.
+        */
+       public function endElement() {
+               if ($this->openElements) {
+                       $this->xml->endElement();
+                       $this->openElements--;
+               }
+       }
+       
+       /**
+        * Writes an element directly.
+        * 
+        * @param       string          $element
+        * @param       string          $cdata
+        * @param       array<string>   $attributes
+        */
+       public function writeElement($element, $cdata, array $attributes = array()) {
+               $this->startElement($element);
+               
+               // write attributes
+               if (!empty($attributes)) {
+                       $this->writeAttributes($attributes);
+               }
+               
+               // content
+               $this->xml->writeCData(StringUtil::escapeCDATA($cdata));
+               
+               $this->endElement();
+       }
+       
+       /**
+        * Writes an attribute to last opened element.
+        * 
+        * @param       string          $attribute
+        * @param       string          $value
+        */
+       public function writeAttribute($attribute, $value) {
+               $this->writeAttributes(array($attribute => $value));
+       }
+       
+       /**
+        * Writes a list of attributes to last opened element.
+        * 
+        * @param       array<string>           $attributes
+        */
+       public function writeAttributes(array $attributes) {
+               foreach ($attributes as $attribute => $value) {
+                       $this->xml->writeAttribute($attribute, $value);
+               }
+       }
+}