2
0
Просмотр исходного кода

ZF-8457: Adding generator based XML generation to speed up things for environments with ext/xmlwriter

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@19561 44c647ce-9c0f-0410-b52a-842ac1e357ba
lars 16 лет назад
Родитель
Сommit
8519db34f2

+ 8 - 9
library/Zend/XmlRpc/Fault.php

@@ -276,7 +276,7 @@ class Zend_XmlRpc_Fault
      *
      *
      * @return string
      * @return string
      */
      */
-    public function saveXML()
+    public function saveXml()
     {
     {
         // Create fault value
         // Create fault value
         $faultStruct = array(
         $faultStruct = array(
@@ -284,16 +284,15 @@ class Zend_XmlRpc_Fault
             'faultString' => $this->getMessage()
             'faultString' => $this->getMessage()
         );
         );
         $value = Zend_XmlRpc_Value::getXmlRpcValue($faultStruct);
         $value = Zend_XmlRpc_Value::getXmlRpcValue($faultStruct);
-        $valueDOM = new DOMDocument('1.0', $this->getEncoding());
-        $valueDOM->loadXML($value->saveXML());
 
 
-        // Build response XML
-        $dom  = new DOMDocument('1.0', $this->getEncoding());
-        $r    = $dom->appendChild($dom->createElement('methodResponse'));
-        $f    = $r->appendChild($dom->createElement('fault'));
-        $f->appendChild($dom->importNode($valueDOM->documentElement, 1));
+        $generator = Zend_XmlRpc_Value::getGenerator();
+        $generator->startElement('methodResponse')
+                  ->startElement('fault');
+        $value->saveXml();
+        $generator->endElement('fault')
+                  ->endElement('methodResponse');
 
 
-        return $dom->saveXML();
+        return $generator->flush();
     }
     }
 
 
     /**
     /**

+ 114 - 0
library/Zend/XmlRpc/Generator/Abstract.php

@@ -0,0 +1,114 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_XmlRpc
+ * @subpackage Generator
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Client.php 17752 2009-08-22 15:49:54Z lars $
+ */
+
+/**
+ * Abstract XML generator adapter
+ */
+abstract class Zend_XmlRpc_Generator_Abstract
+{
+    /**
+     * @var string
+     */
+    protected $_encoding;
+
+    /**
+     * Construct new instance of the generator
+     *
+     * @param string $encoding XML encoding, default UTF-8
+     */
+    public function __construct($encoding = 'UTF-8')
+    {
+        $this->_encoding = $encoding;
+        $this->_init();
+    }
+
+    /**
+     * Start XML element
+     *
+     * Method opens a new XML element with an element name and an optional value
+     * 
+     * @param string $name
+     * @param string $value
+     * @return Zend_XmlRpc_Generator_Abstract Fluent interface
+     */
+    abstract public function startElement($name, $value = null);
+
+    /**
+     * End of an XML element
+     *
+     * Method marks the end of an XML element
+     *
+     * @param string $name
+     * @return Zend_XmlRpc_Generator_Abstract Fluent interface
+     */
+    abstract public function endElement($name);
+
+    /**
+     * Returns XML as a string
+     *
+     * @return string
+     */
+    abstract public function saveXml();
+
+    /**
+     * Return encoding
+     * 
+     * @return string
+     */
+    public function getEncoding()
+    {
+        return $this->_encoding;
+    }
+
+    /**
+     * Returns the XML as a string and flushes all internal buffers
+     *
+     * @return string
+     */
+    public function flush()
+    {
+        $xml = $this->saveXml();
+        $this->_init();
+        return $xml;
+    }
+
+    /**
+     * Returns XML without document declaration
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->_stripXmlDeclaration($this->saveXml());
+    }
+
+    /**
+     * Removes XML declaration from a string
+     *
+     * @param string $xml
+     * @return string
+     */
+    protected function _stripXmlDeclaration($xml)
+    {
+        return preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $xml);
+    }
+}

+ 102 - 0
library/Zend/XmlRpc/Generator/DOMDocument.php

@@ -0,0 +1,102 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_XmlRpc
+ * @subpackage Generator
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Client.php 17752 2009-08-22 15:49:54Z lars $
+ */
+
+/**
+ * @var Zend_XmlRpc_Generator_Abstract
+ */
+require_once 'Zend/XmlRpc/Generator/Abstract.php';
+
+/**
+ * DOMDocument based implementation of a XML/RPC generator
+ */
+class Zend_XmlRpc_Generator_DOMDocument extends Zend_XmlRpc_Generator_Abstract
+{
+    /**
+     * @var DOMDocument
+     */
+    protected $_dom;
+
+    /**
+     * @var DOMNode
+     */
+    protected $_currentElement;
+
+    /**
+     * Start XML element
+     *
+     * Creates a new XML element and appends it to the document tree
+     *
+     * @param string $name
+     * @param string $value
+     * @return Zend_XmlRpc_Generator_DOMDocument Fluent interface
+     */
+    public function startElement($name, $value = null)
+    {
+        $newElement = $this->_dom->createElement($name);
+
+        $this->_currentElement = $this->_currentElement->appendChild($newElement);
+
+        if ($value !== null) {
+            $this->_currentElement->appendChild($this->_dom->createTextNode($value));
+        }
+
+        return $this;
+    }
+
+    /**
+     * End of an XML element
+     *
+     * Resets $_currentElement to the next parent node in the hierarchy
+     *
+     * @param string $name
+     * @return Zend_XmlRpc_Generator_DOMDocument Fluent interface
+     */
+    public function endElement($name)
+    {
+        if (isset($this->_currentElement->parentNode)) {
+            $this->_currentElement = $this->_currentElement->parentNode;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Save XML as a string
+     *
+     * @return string
+     */
+    public function saveXml()
+    {
+        return $this->_dom->saveXml();
+    }
+
+    /**
+     * Initializes internal objects
+     *
+     * @return void
+     */
+    protected function _init()
+    {
+        $this->_dom = new DOMDocument('1.0', $this->_encoding);
+        $this->_currentElement = $this->_dom;
+    }
+}

+ 83 - 0
library/Zend/XmlRpc/Generator/XMLWriter.php

@@ -0,0 +1,83 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_XmlRpc
+ * @subpackage Generator
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Client.php 17752 2009-08-22 15:49:54Z lars $
+ */
+
+/**
+ * @var Zend_XmlRpc_Generator_Abstract
+ */
+require_once 'Zend/XmlRpc/Generator/Abstract.php';
+
+/**
+ * XML generator adapter based on XMLWriter
+ */
+class Zend_XmlRpc_Generator_XMLWriter extends Zend_XmlRpc_Generator_Abstract
+{
+    /**
+     * XMLWriter instance
+     *
+     * @var XMLWriter
+     */
+    protected $_xmlWriter;
+
+    /**
+     * Initialized XMLWriter instance
+     *
+     * @return void
+     */
+    protected function _init()
+    {
+        $this->_xmlWriter = new XMLWriter();
+        $this->_xmlWriter->openMemory();
+        $this->_xmlWriter->startDocument('1.0', $this->_encoding);
+    }
+
+    /**
+     * Start XML element
+     *
+     * Method opens a new XML element with an element name and an optional value
+     *
+     * @param string $name
+     * @param string $value
+     * @return Zend_XmlRpc_Generator_XMLWriter Fluent interface
+     */
+    public function startElement($name, $value = null)
+    {
+        $this->_xmlWriter->startElement($name);
+
+        if ($value !== null) {
+            $this->_xmlWriter->text($value);
+        }
+
+        return $this;
+    }
+
+    public function endElement($name)
+    {
+        $this->_xmlWriter->endElement();
+
+        return $this;
+    }
+
+    public function saveXml()
+    {
+        return $this->_xmlWriter->flush(false);
+    }
+}

+ 13 - 13
library/Zend/XmlRpc/Request.php

@@ -303,7 +303,7 @@ class Zend_XmlRpc_Request
         }
         }
 
 
         try {
         try {
-            $xml = @new SimpleXMLElement($request);
+            $xml = new SimpleXMLElement($request);
         } catch (Exception $e) {
         } catch (Exception $e) {
             // Not valid XML
             // Not valid XML
             $this->_fault = new Zend_XmlRpc_Fault(631);
             $this->_fault = new Zend_XmlRpc_Fault(631);
@@ -401,29 +401,29 @@ class Zend_XmlRpc_Request
      *
      *
      * @return string
      * @return string
      */
      */
-    public function saveXML()
+    public function saveXml()
     {
     {
         $args   = $this->_getXmlRpcParams();
         $args   = $this->_getXmlRpcParams();
         $method = $this->getMethod();
         $method = $this->getMethod();
 
 
-        $dom = new DOMDocument('1.0', $this->getEncoding());
-        $mCall = $dom->appendChild($dom->createElement('methodCall'));
-        $mName = $mCall->appendChild($dom->createElement('methodName', $method));
+        $generator = Zend_XmlRpc_Value::getGenerator();
+        $generator->startElement('methodCall')
+                  ->startElement('methodName', $method)
+                  ->endElement('methodName');
 
 
         if (is_array($args) && count($args)) {
         if (is_array($args) && count($args)) {
-            $params = $mCall->appendChild($dom->createElement('params'));
+            $generator->startElement('params');
 
 
             foreach ($args as $arg) {
             foreach ($args as $arg) {
-                /* @var $arg Zend_XmlRpc_Value */
-                $argDOM = new DOMDocument('1.0', $this->getEncoding());
-                $argDOM->loadXML($arg->saveXML());
-
-                $param = $params->appendChild($dom->createElement('param'));
-                $param->appendChild($dom->importNode($argDOM->documentElement, 1));
+                $generator->startElement('param');
+                $arg->generateXml();
+                $generator->endElement('param');
             }
             }
+            $generator->endElement('params');
         }
         }
+        $generator->endElement('methodCall');
 
 
-        return $dom->saveXML();
+        return $generator->flush();
     }
     }
 
 
     /**
     /**

+ 12 - 13
library/Zend/XmlRpc/Response.php

@@ -176,7 +176,7 @@ class Zend_XmlRpc_Response
         }
         }
 
 
         try {
         try {
-            $xml = @new SimpleXMLElement($response);
+            $xml = new SimpleXMLElement($response);
         } catch (Exception $e) {
         } catch (Exception $e) {
             // Not valid XML
             // Not valid XML
             $this->_fault = new Zend_XmlRpc_Fault(651);
             $this->_fault = new Zend_XmlRpc_Fault(651);
@@ -221,20 +221,19 @@ class Zend_XmlRpc_Response
      *
      *
      * @return string
      * @return string
      */
      */
-    public function saveXML()
+    public function saveXml()
     {
     {
         $value = $this->_getXmlRpcReturn();
         $value = $this->_getXmlRpcReturn();
-        $valueDOM = new DOMDocument('1.0', $this->getEncoding());
-        $valueDOM->loadXML($value->saveXML());
-
-        $dom      = new DOMDocument('1.0', $this->getEncoding());
-        $response = $dom->appendChild($dom->createElement('methodResponse'));
-        $params   = $response->appendChild($dom->createElement('params'));
-        $param    = $params->appendChild($dom->createElement('param'));
-
-        $param->appendChild($dom->importNode($valueDOM->documentElement, true));
-
-        return $dom->saveXML();
+        $generator = Zend_XmlRpc_Value::getGenerator();
+        $generator->startElement('methodResponse')
+                  ->startElement('params')
+                  ->startElement('param');
+        $value->generateXml();
+        $generator->endElement('param')
+                  ->endElement('params')
+                  ->endElement('methodResponse');
+
+        return $generator->flush();
     }
     }
 
 
     /**
     /**

+ 37 - 22
library/Zend/XmlRpc/Value.php

@@ -53,12 +53,12 @@ abstract class Zend_XmlRpc_Value
     /**
     /**
      * XML code representation of this object (will be calculated only once)
      * XML code representation of this object (will be calculated only once)
      */
      */
-    protected $_as_xml;
+    protected $_xml;
 
 
     /**
     /**
-     * DOMElement representation of object (will be calculated only once)
+     * @var Zend_XmlRpc_Generator_Abstract
      */
      */
-    protected $_as_dom;
+    protected static $_generator;
 
 
     /**
     /**
      * Specify that the XML-RPC native type will be auto detected from a PHP variable type
      * Specify that the XML-RPC native type will be auto detected from a PHP variable type
@@ -97,6 +97,20 @@ abstract class Zend_XmlRpc_Value
         return $this->_type;
         return $this->_type;
     }
     }
 
 
+    public static function getGenerator()
+    {
+        if (!self::$_generator) {
+            require_once 'Zend/XmlRpc/Generator/DOMDocument.php';
+            self::$_generator = new Zend_XmlRpc_Generator_DOMDocument();
+        }
+
+        return self::$_generator;
+    }
+
+    public static function setGenerator(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        self::$_generator = $generator;
+    }
 
 
     /**
     /**
      * Return the value of this object, convert the XML-RPC native value into a PHP variable
      * Return the value of this object, convert the XML-RPC native value into a PHP variable
@@ -111,31 +125,24 @@ abstract class Zend_XmlRpc_Value
      *
      *
      * @return string
      * @return string
      */
      */
-    abstract public function saveXML();
-
-    /**
-     * Return DOMElement representation of object
-     *
-     * @return DOMElement
-     */
-    public function getAsDOM()
+    public function saveXml()
     {
     {
-        if (!$this->_as_dom) {
-            $doc = new DOMDocument('1.0');
-            $doc->loadXML($this->saveXML());
-            $this->_as_dom = $doc->documentElement;
+        if (!$this->_xml) {
+            $this->generateXml();
         }
         }
-
-        return $this->_as_dom;
+        return $this->_xml;
     }
     }
 
 
     /**
     /**
-     * @param DOMDocument $dom
-     * @return mixed
+     * Generate XML code that represent a native XML/RPC value
+     *
+     * @return void
      */
      */
-    protected function _stripXmlDeclaration(DOMDocument $dom)
+    public function generateXml()
     {
     {
-        return preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $dom->saveXML());
+        if (!$this->_xml) {
+            $this->_generateXml();
+        }
     }
     }
 
 
     /**
     /**
@@ -438,9 +445,17 @@ abstract class Zend_XmlRpc_Value
      */
      */
     protected function _setXML($xml)
     protected function _setXML($xml)
     {
     {
-        $this->_as_xml = $xml;
+        $this->_xml = $this->_stripXmlDeclaration($xml);
     }
     }
 
 
+    /**
+     * @param DOMDocument $dom
+     * @return mixed
+     */
+    protected function _stripXmlDeclaration($xml)
+    {
+        return preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $xml);
+    }
 
 
     /**
     /**
      * Make sure a string will be safe for XML, convert risky characters to entities
      * Make sure a string will be safe for XML, convert risky characters to entities

+ 14 - 17
library/Zend/XmlRpc/Value/Array.php

@@ -49,30 +49,27 @@ class Zend_XmlRpc_Value_Array extends Zend_XmlRpc_Value_Collection
 
 
 
 
     /**
     /**
-     * Return the XML code that represent an array native MXL-RPC value
+     * Generate the XML code that represent an array native MXL-RPC value
      *
      *
-     * @return string
+     * @return void
      */
      */
-    public function saveXML()
+    protected function _generateXml()
     {
     {
-        if (!$this->_as_xml) {   // The XML code was not calculated yet
-            $dom   = new DOMDocument('1.0');
-            $value = $dom->appendChild($dom->createElement('value'));
-            $array = $value->appendChild($dom->createElement('array'));
-            $data  = $array->appendChild($dom->createElement('data'));
+        $generator = $this->getGenerator();
+        $generator->startElement('value')
+                  ->startElement('array')
+                  ->startElement('data');
 
 
-            if (is_array($this->_value)) {
-                foreach ($this->_value as $val) {
-                    /* @var $val Zend_XmlRpc_Value */
-                    $data->appendChild($dom->importNode($val->getAsDOM(), true));
-                }
+        if (is_array($this->_value)) {
+            foreach ($this->_value as $val) {
+                $val->generateXml();
             }
             }
-
-            $this->_as_dom = $value;
-            $this->_as_xml = $this->_stripXmlDeclaration($dom);
         }
         }
+        $generator->endElement('data')
+                  ->endElement('array')
+                  ->endElement('value');
 
 
-        return $this->_as_xml;
+        $this->_xml = (string)$generator;
     }
     }
 }
 }
 
 

+ 3 - 24
library/Zend/XmlRpc/Value/Base64.php

@@ -44,12 +44,12 @@ class Zend_XmlRpc_Value_Base64 extends Zend_XmlRpc_Value_Scalar
      * @param string $value
      * @param string $value
      * @param bool $already_encoded If set, it means that the given string is already base64 encoded
      * @param bool $already_encoded If set, it means that the given string is already base64 encoded
      */
      */
-    public function __construct($value, $already_encoded=false)
+    public function __construct($value, $alreadyEncoded = false)
     {
     {
         $this->_type = self::XMLRPC_TYPE_BASE64;
         $this->_type = self::XMLRPC_TYPE_BASE64;
 
 
         $value = (string)$value;    // Make sure this value is string
         $value = (string)$value;    // Make sure this value is string
-        if (!$already_encoded) {
+        if (!$alreadyEncoded) {
             $value = base64_encode($value);     // We encode it in base64
             $value = base64_encode($value);     // We encode it in base64
         }
         }
         $this->_value = $value;
         $this->_value = $value;
@@ -65,25 +65,4 @@ class Zend_XmlRpc_Value_Base64 extends Zend_XmlRpc_Value_Scalar
     {
     {
         return base64_decode($this->_value);
         return base64_decode($this->_value);
     }
     }
-
-    /**
-     * Return the XML code representing the base64-encoded value
-     *
-     * @return string
-     */
-    public function saveXML()
-    {
-        if (! $this->_as_xml) {   // The XML was not generated yet
-            $dom   = new DOMDocument('1.0', 'UTF-8');
-            $value = $dom->appendChild($dom->createElement('value'));
-            $type  = $value->appendChild($dom->createElement($this->_type));
-            $type->appendChild($dom->createTextNode($this->_value));
-
-            $this->_as_dom = $value;
-            $this->_as_xml = $this->_stripXmlDeclaration($dom);
-        }
-
-        return $this->_as_xml;
-    }
-}
-
+}

+ 1 - 22
library/Zend/XmlRpc/Value/Boolean.php

@@ -60,25 +60,4 @@ class Zend_XmlRpc_Value_Boolean extends Zend_XmlRpc_Value_Scalar
     {
     {
         return (bool)$this->_value;
         return (bool)$this->_value;
     }
     }
-
-    /**
-     * Return the XML-RPC serialization of the boolean value
-     *
-     * @return string
-     */
-    public function saveXML()
-    {
-        if (! $this->_as_xml) {   // The XML was not generated yet
-            $dom   = new DOMDocument('1.0', 'UTF-8');
-            $value = $dom->appendChild($dom->createElement('value'));
-            $type  = $value->appendChild($dom->createElement($this->_type));
-            $type->appendChild($dom->createTextNode($this->_value));
-
-            $this->_as_dom = $value;
-            $this->_as_xml = $this->_stripXmlDeclaration($dom);
-        }
-
-        return $this->_as_xml;
-    }
-}
-
+}

+ 10 - 14
library/Zend/XmlRpc/Value/Scalar.php

@@ -36,24 +36,20 @@ require_once 'Zend/XmlRpc/Value.php';
  */
  */
 abstract class Zend_XmlRpc_Value_Scalar extends Zend_XmlRpc_Value
 abstract class Zend_XmlRpc_Value_Scalar extends Zend_XmlRpc_Value
 {
 {
-
     /**
     /**
-     * Return the XML code that represent a scalar native MXL-RPC value
+     * Generate the XML code that represent a scalar native MXL-RPC value
      *
      *
-     * @return string
+     * @return void
      */
      */
-    public function saveXML()
+    protected function _generateXml()
     {
     {
-        if (!$this->_as_xml) {   // The XML code was not calculated yet
-            $dom   = new DOMDocument('1.0');
-            $value = $dom->appendChild($dom->createElement('value'));
-            $type  = $value->appendChild($dom->createElement($this->_type));
-            $type->appendChild($dom->createTextNode($this->getValue()));
+        $generator = $this->getGenerator();
 
 
-            $this->_as_dom = $value;
-            $this->_as_xml = $this->_stripXmlDeclaration($dom);
-        }
+        $generator->startElement('value')
+                  ->startElement($this->_type, $this->_value)
+                  ->endElement($this->_type)
+                  ->endElement('value');
 
 
-        return $this->_as_xml;
+        $this->_xml = (string)$generator;
     }
     }
-}
+}

+ 18 - 21
library/Zend/XmlRpc/Value/Struct.php

@@ -49,31 +49,28 @@ class Zend_XmlRpc_Value_Struct extends Zend_XmlRpc_Value_Collection
 
 
 
 
     /**
     /**
-     * Return the XML code that represent struct native MXL-RPC value
+     * Generate the XML code that represent struct native MXL-RPC value
      *
      *
-     * @return string
+     * @return void
      */
      */
-    public function saveXML()
+    protected function _generateXML()
     {
     {
-        if (!$this->_as_xml) {   // The XML code was not calculated yet
-            $dom    = new DOMDocument('1.0');
-            $value  = $dom->appendChild($dom->createElement('value'));
-            $struct = $value->appendChild($dom->createElement('struct'));
+        $generator = $this->getGenerator();
+        $generator->startElement('value')
+                  ->startElement('struct');
 
 
-            if (is_array($this->_value)) {
-                foreach ($this->_value as $name => $val) {
-                    /* @var $val Zend_XmlRpc_Value */
-                    $member = $struct->appendChild($dom->createElement('member'));
-                    $member->appendChild($dom->createElement('name', $this->_escapeXmlEntities($name)));
-                    $member->appendChild($dom->importNode($val->getAsDOM(), 1));
-                }
+        if (is_array($this->_value)) {
+            foreach ($this->_value as $name => $val) {
+                /* @var $val Zend_XmlRpc_Value */
+                $generator->startElement('member')
+                          ->startElement('name', $name)
+                          ->endElement('name');
+                $val->generateXml();
+                $generator->endElement('member');
             }
             }
-
-            $this->_as_dom = $value;
-            $this->_as_xml = $this->_stripXmlDeclaration($dom);
         }
         }
-
-        return $this->_as_xml;
+        $generator->endElement('struct')
+                  ->endElement('value');
+        $this->_xml = (string)$generator;
     }
     }
-}
-
+}

+ 2 - 0
tests/Zend/XmlRpc/AllTests.php

@@ -32,6 +32,7 @@ require_once 'Zend/XmlRpc/ResponseTest.php';
 require_once 'Zend/XmlRpc/FaultTest.php';
 require_once 'Zend/XmlRpc/FaultTest.php';
 require_once 'Zend/XmlRpc/ClientTest.php';
 require_once 'Zend/XmlRpc/ClientTest.php';
 require_once 'Zend/XmlRpc/ServerTest.php';
 require_once 'Zend/XmlRpc/ServerTest.php';
+require_once 'Zend/XmlRpc/GeneratorTest.php';
 require_once 'Zend/XmlRpc/Server/CacheTest.php';
 require_once 'Zend/XmlRpc/Server/CacheTest.php';
 require_once 'Zend/XmlRpc/Server/FaultTest.php';
 require_once 'Zend/XmlRpc/Server/FaultTest.php';
 
 
@@ -61,6 +62,7 @@ class Zend_XmlRpc_AllTests
         $suite->addTestSuite('Zend_XmlRpc_FaultTest');
         $suite->addTestSuite('Zend_XmlRpc_FaultTest');
         $suite->addTestSuite('Zend_XmlRpc_ClientTest');
         $suite->addTestSuite('Zend_XmlRpc_ClientTest');
         $suite->addTestSuite('Zend_XmlRpc_ServerTest');
         $suite->addTestSuite('Zend_XmlRpc_ServerTest');
+        $suite->addTestSuite('Zend_XmlRpc_GeneratorTest');
         $suite->addTestSuite('Zend_XmlRpc_Server_CacheTest');
         $suite->addTestSuite('Zend_XmlRpc_Server_CacheTest');
         $suite->addTestSuite('Zend_XmlRpc_Server_FaultTest');
         $suite->addTestSuite('Zend_XmlRpc_Server_FaultTest');
 
 

+ 3 - 3
tests/Zend/XmlRpc/ClientTest.php

@@ -327,7 +327,7 @@ class Zend_XmlRpc_ClientTest extends PHPUnit_Framework_TestCase
         $message = 'foo';
         $message = 'foo';
 
 
         $fault = new Zend_XmlRpc_Fault($code, $message);
         $fault = new Zend_XmlRpc_Fault($code, $message);
-        $xml = $fault->saveXML();
+        $xml = $fault->saveXml();
 
 
         $response = $this->makeHttpResponseFrom($xml);
         $response = $this->makeHttpResponseFrom($xml);
         $this->httpAdapter->setResponse($response);
         $this->httpAdapter->setResponse($response);
@@ -578,7 +578,7 @@ class Zend_XmlRpc_ClientTest extends PHPUnit_Framework_TestCase
 
 
         // system.multicall() will return a fault
         // system.multicall() will return a fault
         $fault = new Zend_XmlRpc_Fault(7, 'bad method');
         $fault = new Zend_XmlRpc_Fault(7, 'bad method');
-        $xml = $fault->saveXML();
+        $xml = $fault->saveXml();
         $response = $this->makeHttpResponseFrom($xml);
         $response = $this->makeHttpResponseFrom($xml);
         $this->httpAdapter->addResponse($response);
         $this->httpAdapter->addResponse($response);
 
 
@@ -673,7 +673,7 @@ class Zend_XmlRpc_ClientTest extends PHPUnit_Framework_TestCase
     {
     {
         $response = new Zend_XmlRpc_Response();
         $response = new Zend_XmlRpc_Response();
         $response->setReturnValue($nativeVars);
         $response->setReturnValue($nativeVars);
-        $xml = $response->saveXML();
+        $xml = $response->saveXml();
 
 
         $response = $this->makeHttpResponseFrom($xml);
         $response = $this->makeHttpResponseFrom($xml);
         return $response;
         return $response;

+ 5 - 5
tests/Zend/XmlRpc/FaultTest.php

@@ -104,7 +104,7 @@ class Zend_XmlRpc_FaultTest extends PHPUnit_Framework_TestCase
             $value2 = $member2->appendChild($dom->createElement('value'));
             $value2 = $member2->appendChild($dom->createElement('value'));
             $value2->appendChild($dom->createElement('string', 'Error string'));
             $value2->appendChild($dom->createElement('string', 'Error string'));
 
 
-        return $dom->saveXML();
+        return $dom->saveXml();
     }
     }
 
 
     protected function _createNonStandardXml()
     protected function _createNonStandardXml()
@@ -124,7 +124,7 @@ class Zend_XmlRpc_FaultTest extends PHPUnit_Framework_TestCase
             $member2->appendChild($dom->createElement('name', 'faultString'));
             $member2->appendChild($dom->createElement('name', 'faultString'));
             $value2 = $member2->appendChild($dom->createElement('value', 'Error string'));
             $value2 = $member2->appendChild($dom->createElement('value', 'Error string'));
 
 
-        return $dom->saveXML();
+        return $dom->saveXml();
     }
     }
 
 
     /**
     /**
@@ -210,7 +210,7 @@ class Zend_XmlRpc_FaultTest extends PHPUnit_Framework_TestCase
     }
     }
 
 
     /**
     /**
-     * helper for saveXML() and __toString() tests
+     * helper for saveXml() and __toString() tests
      *
      *
      * @param string $xml
      * @param string $xml
      * @return void
      * @return void
@@ -245,13 +245,13 @@ class Zend_XmlRpc_FaultTest extends PHPUnit_Framework_TestCase
     }
     }
 
 
     /**
     /**
-     * saveXML() test
+     * saveXml() test
      */
      */
     public function testSaveXML()
     public function testSaveXML()
     {
     {
         $this->_fault->setCode(1000);
         $this->_fault->setCode(1000);
         $this->_fault->setMessage('Fault message');
         $this->_fault->setMessage('Fault message');
-        $xml = $this->_fault->saveXML();
+        $xml = $this->_fault->saveXml();
         $this->_testXmlFault($xml);
         $this->_testXmlFault($xml);
     }
     }
 
 

+ 135 - 0
tests/Zend/XmlRpc/GeneratorTest.php

@@ -0,0 +1,135 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_XmlRpc
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version $Id: ValueTest.php 18442 2009-09-30 13:17:48Z lars $
+ */
+
+// Call Zend_XmlRpc_ValueTest::main() if this source file is executed directly.
+if (!defined("PHPUnit_MAIN_METHOD")) {
+    require_once dirname(__FILE__) . '/../../TestHelper.php';
+    define("PHPUnit_MAIN_METHOD", "Zend_XmlRpc_ValueTest::main");
+}
+
+require_once "PHPUnit/Framework/TestCase.php";
+require_once "PHPUnit/Framework/TestSuite.php";
+require_once 'Zend/XmlRpc/Generator/DOMDocument.php';
+require_once 'Zend/XmlRpc/Generator/XMLWriter.php';
+require_once 'Zend/XmlRpc/TestProvider.php';
+
+/**
+ * Test case for Zend_XmlRpc_Generator_*
+ *
+ * @category   Zend
+ * @package    Zend_XmlRpc
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @group      Zend_XmlRpc
+ */
+class Zend_XmlRpc_GeneratorTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testCreatingSingleElement(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $generator->startElement('element');
+        $generator->endElement('element');
+        $this->assertXml('<element/>', $generator);
+    }
+
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testCreatingSingleElementWithValue(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $generator->startElement('element', 'value');
+        $generator->endElement('element');
+        $this->assertXml('<element>value</element>', $generator);
+    }
+
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testCreatingComplexXmlDocument(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $generator->startElement('root');
+        $generator->startElement('children');
+        $generator->startElement('child', 'child1')->endElement('child');
+        $generator->startElement('child', 'child2')->endElement('child');
+        $generator->endElement('children');
+        $generator->endElement('root');
+        $this->assertXml(
+            '<root><children><child>child1</child><child>child2</child></children></root>',
+            $generator
+        );
+    }
+
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testFlushingGeneratorFlushesEverything(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $generator->startElement('test')->endElement('test');
+        $this->assertXml('<test/>', $generator);
+        $this->assertContains('<test/>', $generator->flush());
+        $this->assertSame('', (string)$generator);
+    }
+
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testSpecialCharsAreEncoded(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $generator->startElement('element', '<>&"\'€')->endElement('element');
+        $variant1 = '<element>&lt;&gt;&amp;"\'€</element>';
+        $variant2 = '<element>&lt;&gt;&amp;&quot;\'€</element>';
+        try {
+            $this->assertXml($variant1, $generator);
+        } catch (PHPUnit_Framework_ExpectationFailedException $e) {
+            $this->assertXml($variant2, $generator);
+        }
+    }
+
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGeneratorsWithAlternateEncodings
+     */
+    public function testDifferentEncodings(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $generator->startElement('element', '€')->endElement('element');
+        $this->assertXml('<element>&#8364;</element>', $generator);
+    }
+
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testFluentInterfacesProvided(Zend_XmlRpc_Generator_Abstract $generator)
+    {
+        $this->assertSame($generator, $generator->startElement('foo'));
+        $this->assertSame($generator, $generator->endElement('foo'));
+    }
+
+    public function assertXml($expected, $actual)
+    {
+        $expected = trim($expected);
+        $this->assertSame($expected, trim($actual));
+        $xmlDecl = '<?xml version="1.0" encoding="' . $actual->getEncoding() . '"?>' . "\n";
+        $this->assertSame($xmlDecl . $expected, trim($actual->saveXml()));
+    }
+}

+ 4 - 4
tests/Zend/XmlRpc/RequestTest.php

@@ -121,7 +121,7 @@ class Zend_XmlRpc_RequestTest extends PHPUnit_Framework_TestCase
         $time = time();
         $time = time();
         $this->_request->addParam($time, Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME);
         $this->_request->addParam($time, Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME);
         $this->_request->setMethod('foo.bar');
         $this->_request->setMethod('foo.bar');
-        $xml = $this->_request->saveXML();
+        $xml = $this->_request->saveXml();
         $sxl = new SimpleXMLElement($xml);
         $sxl = new SimpleXMLElement($xml);
         $param = $sxl->params->param->value;
         $param = $sxl->params->param->value;
         $type  = 'dateTime.iso8601';
         $type  = 'dateTime.iso8601';
@@ -182,7 +182,7 @@ class Zend_XmlRpc_RequestTest extends PHPUnit_Framework_TestCase
             $value2->appendChild($dom->createElement('boolean', 1));
             $value2->appendChild($dom->createElement('boolean', 1));
 
 
 
 
-        $xml = $dom->saveXML();
+        $xml = $dom->saveXml();
 
 
         try {
         try {
             $parsed = $this->_request->loadXml($xml);
             $parsed = $this->_request->loadXml($xml);
@@ -272,7 +272,7 @@ class Zend_XmlRpc_RequestTest extends PHPUnit_Framework_TestCase
     }
     }
 
 
     /**
     /**
-     * helper for saveXML() and __toString() tests
+     * helper for saveXml() and __toString() tests
      *
      *
      * @param string $xml
      * @param string $xml
      * @return void
      * @return void
@@ -321,7 +321,7 @@ class Zend_XmlRpc_RequestTest extends PHPUnit_Framework_TestCase
         $argv = array('string', true);
         $argv = array('string', true);
         $this->_request->setMethod('do.Something');
         $this->_request->setMethod('do.Something');
         $this->_request->setParams($argv);
         $this->_request->setParams($argv);
-        $xml = $this->_request->saveXML();
+        $xml = $this->_request->saveXml();
         $this->_testXmlRequest($xml, $argv);
         $this->_testXmlRequest($xml, $argv);
     }
     }
 
 

+ 4 - 4
tests/Zend/XmlRpc/ResponseTest.php

@@ -122,7 +122,7 @@ class Zend_XmlRpc_ResponseTest extends PHPUnit_Framework_TestCase
         $value    = $param->appendChild($dom->createElement('value'));
         $value    = $param->appendChild($dom->createElement('value'));
         $value->appendChild($dom->createElement('string', 'Return value'));
         $value->appendChild($dom->createElement('string', 'Return value'));
 
 
-        $xml = $dom->saveXML();
+        $xml = $dom->saveXml();
 
 
         $parsed = $this->_response->loadXml($xml);
         $parsed = $this->_response->loadXml($xml);
         $this->assertTrue($parsed, $xml);
         $this->assertTrue($parsed, $xml);
@@ -162,7 +162,7 @@ EOD;
     }
     }
 
 
     /**
     /**
-     * helper for saveXML() and __toString() tests
+     * helper for saveXml() and __toString() tests
      *
      *
      * @param string $xml
      * @param string $xml
      * @return void
      * @return void
@@ -183,12 +183,12 @@ EOD;
     }
     }
 
 
     /**
     /**
-     * saveXML() test
+     * saveXml() test
      */
      */
     public function testSaveXML()
     public function testSaveXML()
     {
     {
         $this->_response->setReturnValue('return value');
         $this->_response->setReturnValue('return value');
-        $xml = $this->_response->saveXML();
+        $xml = $this->_response->saveXml();
         $this->_testXmlResponse($xml);
         $this->_testXmlResponse($xml);
     }
     }
 
 

+ 2 - 3
tests/Zend/XmlRpc/Server/FaultTest.php

@@ -243,13 +243,12 @@ class Zend_XmlRpc_Server_FaultTest extends PHPUnit_Framework_TestCase
 
 
         $xml = $dom->saveXML();
         $xml = $dom->saveXML();
 
 
+        require_once 'Zend/XmlRpc/Server/Exception.php';
         $e = new Zend_XmlRpc_Server_Exception('Testing fault', 411);
         $e = new Zend_XmlRpc_Server_Exception('Testing fault', 411);
         $fault = Zend_XmlRpc_Server_Fault::getInstance($e);
         $fault = Zend_XmlRpc_Server_Fault::getInstance($e);
 
 
-        $this->assertEquals($xml, $fault->__toString());
+        $this->assertEquals(trim($xml), trim($fault->__toString()));
     }
     }
-
-
 }
 }
 
 
 class zxrs_fault_test_exception extends Exception {}
 class zxrs_fault_test_exception extends Exception {}

+ 39 - 0
tests/Zend/XmlRpc/TestProvider.php

@@ -0,0 +1,39 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_XmlRpc
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version $Id: ValueTest.php 18442 2009-09-30 13:17:48Z lars $
+ */
+abstract class Zend_XmlRpc_TestProvider
+{
+    public static function provideGenerators()
+    {
+        return array(
+            array(new Zend_XmlRpc_Generator_DOMDocument()),
+            array(new Zend_XmlRpc_Generator_XMLWriter()),
+        );
+    }
+
+    public static function provideGeneratorsWithAlternateEncodings()
+    {
+        return array(
+            array(new Zend_XmlRpc_Generator_DOMDocument('ISO-8859-1')),
+            array(new Zend_XmlRpc_Generator_XMLWriter('ISO-8859-1')),
+        );
+    }
+}

+ 113 - 56
tests/Zend/XmlRpc/ValueTest.php

@@ -43,6 +43,9 @@ require_once 'Zend/XmlRpc/Value/String.php';
 require_once 'Zend/XmlRpc/Value/Nil.php';
 require_once 'Zend/XmlRpc/Value/Nil.php';
 require_once 'Zend/XmlRpc/Value/Struct.php';
 require_once 'Zend/XmlRpc/Value/Struct.php';
 require_once 'Zend/Crypt/Math/BigInteger.php';
 require_once 'Zend/Crypt/Math/BigInteger.php';
+require_once 'Zend/XmlRpc/Generator/DOMDocument.php';
+require_once 'Zend/XmlRpc/Generator/XMLWriter.php';
+require_once 'Zend/XmlRpc/TestProvider.php';
 
 
 /**
 /**
  * Test case for Zend_XmlRpc_Value
  * Test case for Zend_XmlRpc_Value
@@ -89,8 +92,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
     }
     }
 
 
-    public function testMarshalBooleanFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalBooleanFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $xml = '<value><boolean>1</boolean></value>';
         $xml = '<value><boolean>1</boolean></value>';
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
                                     Zend_XmlRpc_Value::XML_STRING);
                                     Zend_XmlRpc_Value::XML_STRING);
@@ -98,8 +105,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('boolean', $val);
         $this->assertXmlRpcType('boolean', $val);
         $this->assertEquals('boolean', $val->getType());
         $this->assertEquals('boolean', $val->getType());
         $this->assertSame(true, $val->getValue());
         $this->assertSame(true, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     // Integer
     // Integer
@@ -123,8 +129,13 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         }
         }
     }
     }
 
 
-    public function testMarshalIntegerFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalIntegerFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
+
         $native = 1;
         $native = 1;
         $xmls = array("<value><int>$native</int></value>",
         $xmls = array("<value><int>$native</int></value>",
                       "<value><i4>$native</i4></value>");
                       "<value><i4>$native</i4></value>");
@@ -135,8 +146,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
             $this->assertXmlRpcType('integer', $val);
             $this->assertXmlRpcType('integer', $val);
             $this->assertEquals('int', $val->getType());
             $this->assertEquals('int', $val->getType());
             $this->assertSame($native, $val->getValue());
             $this->assertSame($native, $val->getValue());
-            $this->assertType('DomElement', $val->getAsDOM());
-            $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+            $this->assertEquals($this->wrapXml($xml), $val->saveXml());
         }
         }
     }
     }
 
 
@@ -162,9 +172,11 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
 
 
     /**
     /**
      * @group ZF-6445
      * @group ZF-6445
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
      */
      */
-    public function testMarshalBigIntegerFromFromXmlRpc()
+    public function testMarshalBigIntegerFromFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $bigInt = (string)(PHP_INT_MAX + 1);
         $bigInt = (string)(PHP_INT_MAX + 1);
         $native = new Zend_Crypt_Math_BigInteger();
         $native = new Zend_Crypt_Math_BigInteger();
         $native->init($bigInt);
         $native->init($bigInt);
@@ -176,7 +188,6 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
             $value = Zend_XmlRpc_Value::getXmlRpcValue($xml, Zend_XmlRpc_Value::XML_STRING);
             $value = Zend_XmlRpc_Value::getXmlRpcValue($xml, Zend_XmlRpc_Value::XML_STRING);
             $this->assertEquals($native, $value->getValue());
             $this->assertEquals($native, $value->getValue());
             $this->assertEquals('i8', $value->getType());
             $this->assertEquals('i8', $value->getType());
-            $this->assertType('DOMElement', $value->getAsDOM());
             $this->assertEquals($this->wrapXml($xml), $value->saveXml());
             $this->assertEquals($this->wrapXml($xml), $value->saveXml());
         }
         }
     }
     }
@@ -218,8 +229,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
     }
     }
 
 
-    public function testMarshalDoubleFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalDoubleFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = 1.1;
         $native = 1.1;
         $xml = "<value><double>$native</double></value>";
         $xml = "<value><double>$native</double></value>";
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
@@ -228,8 +243,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('double', $val);
         $this->assertXmlRpcType('double', $val);
         $this->assertEquals('double', $val->getType());
         $this->assertEquals('double', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     /**
     /**
@@ -266,8 +280,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
     }
     }
 
 
-    public function testMarshalStringFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalStringFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = 'foo';
         $native = 'foo';
         $xml = "<value><string>$native</string></value>";
         $xml = "<value><string>$native</string></value>";
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
@@ -276,12 +294,15 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('string', $val);
         $this->assertXmlRpcType('string', $val);
         $this->assertEquals('string', $val->getType());
         $this->assertEquals('string', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
-    public function testMarshalStringFromDefault()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalStringFromDefault(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = 'foo';
         $native = 'foo';
         $xml = "<string>$native</string>";
         $xml = "<string>$native</string>";
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
@@ -290,8 +311,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('string', $val);
         $this->assertXmlRpcType('string', $val);
         $this->assertEquals('string', $val->getType());
         $this->assertEquals('string', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     //Nil
     //Nil
@@ -315,8 +335,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         }
         }
     }
     }
 
 
-    public function testMarshalNilFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalNilFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $xmls = array('<value><nil/></value>',
         $xmls = array('<value><nil/></value>',
                      '<value><ex:nil xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"/></value>');
                      '<value><ex:nil xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions"/></value>');
 
 
@@ -326,8 +350,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
             $this->assertXmlRpcType('nil', $val);
             $this->assertXmlRpcType('nil', $val);
             $this->assertEquals('nil', $val->getType());
             $this->assertEquals('nil', $val->getType());
             $this->assertSame(NULL, $val->getValue());
             $this->assertSame(NULL, $val->getValue());
-            $this->assertType('DomElement', $val->getAsDOM());
-            $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+            $this->assertEquals($this->wrapXml($xml), $val->saveXml());
         }
         }
     }
     }
 
 
@@ -349,8 +372,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
     }
     }
 
 
-    public function testMarshalArrayFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalArrayFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array(0,1);
         $native = array(0,1);
         $xml = '<value><array><data><value><int>0</int></value>'
         $xml = '<value><array><data><value><int>0</int></value>'
              . '<value><int>1</int></value></data></array></value>';
              . '<value><int>1</int></value></data></array></value>';
@@ -361,12 +388,15 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('array', $val);
         $this->assertXmlRpcType('array', $val);
         $this->assertEquals('array', $val->getType());
         $this->assertEquals('array', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
-    public function testEmptyXmlRpcArrayResultsInEmptyArray()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testEmptyXmlRpcArrayResultsInEmptyArray(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array();
         $native = array();
         $xml    = '<value><array><data/></array></value>';
         $xml    = '<value><array><data/></array></value>';
 
 
@@ -383,8 +413,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $value->getValue());
         $this->assertSame($native, $value->getValue());
     }
     }
 
 
-    public function testArrayMustContainDataElement()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testArrayMustContainDataElement(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array();
         $native = array();
         $xml    = '<value><array/></value>';
         $xml    = '<value><array/></value>';
 
 
@@ -396,9 +430,11 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
 
 
     /**
     /**
      * @group ZF-5405
      * @group ZF-5405
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
      */
      */
-    public function testMarshalNilInStructWrappedInArray()
+    public function testMarshalNilInStructWrappedInArray(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $expected = array(array('id' => '1', 'name' => 'vertebra, caudal', 'description' => null));
         $expected = array(array('id' => '1', 'name' => 'vertebra, caudal', 'description' => null));
         $xml = '<value>'
         $xml = '<value>'
              . '<array><data><value><struct><member><name>id</name><value><string>1</string></value></member>'
              . '<array><data><value><struct><member><name>id</name><value><string>1</string></value></member>'
@@ -433,8 +469,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
     }
     }
 
 
-    public function testMarshalStructFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalStructFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array('foo' => 0);
         $native = array('foo' => 0);
         $xml = '<value><struct><member><name>foo</name><value><int>0</int>'
         $xml = '<value><struct><member><name>foo</name><value><int>0</int>'
              . '</value></member></struct></value>';
              . '</value></member></struct></value>';
@@ -445,12 +485,15 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('struct', $val);
         $this->assertXmlRpcType('struct', $val);
         $this->assertEquals('struct', $val->getType());
         $this->assertEquals('struct', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
-    public function testMarshallingStructWithMemberWithoutValue()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshallingStructWithMemberWithoutValue(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array('foo' => 0, 'bar' => 1);
         $native = array('foo' => 0, 'bar' => 1);
         $xml = '<value><struct>'
         $xml = '<value><struct>'
              . '<member><name>foo</name><value><int>0</int></value></member>'
              . '<member><name>foo</name><value><int>0</int></value></member>'
@@ -464,12 +507,15 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('struct', $val);
         $this->assertXmlRpcType('struct', $val);
         $this->assertEquals('struct', $val->getType());
         $this->assertEquals('struct', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
-    public function testMarshallingStructWithMemberWithoutName()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshallingStructWithMemberWithoutName(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array('foo' => 0, 'bar' => 1);
         $native = array('foo' => 0, 'bar' => 1);
         $xml = '<value><struct>'
         $xml = '<value><struct>'
              . '<member><name>foo</name><value><int>0</int></value></member>'
              . '<member><name>foo</name><value><int>0</int></value></member>'
@@ -483,32 +529,35 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('struct', $val);
         $this->assertXmlRpcType('struct', $val);
         $this->assertEquals('struct', $val->getType());
         $this->assertEquals('struct', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     /**
     /**
      * @group ZF-7639
      * @group ZF-7639
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
      */
      */
-    public function testMarshalStructFromXmlRpcWithEntities()
+    public function testMarshalStructFromXmlRpcWithEntities(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array('&nbsp;' => 0);
         $native = array('&nbsp;' => 0);
         $xml = '<value><struct><member><name>&amp;nbsp;</name><value><int>0</int>'
         $xml = '<value><struct><member><name>&amp;nbsp;</name><value><int>0</int>'
              . '</value></member></struct></value>';
              . '</value></member></struct></value>';
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml, Zend_XmlRpc_Value::XML_STRING);
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml, Zend_XmlRpc_Value::XML_STRING);
         $this->assertXmlRpcType('struct', $val);
         $this->assertXmlRpcType('struct', $val);
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertSame($this->wrapXml($xml), $val->saveXML());
+        $this->assertSame($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     /**
     /**
      * @group ZF-3947
      * @group ZF-3947
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
      */
      */
-    public function testMarshallingStructsWithEmptyValueFromXmlRpcShouldRetainKeys()
+    public function testMarshallingStructsWithEmptyValueFromXmlRpcShouldRetainKeys(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array('foo' => '');
         $native = array('foo' => '');
         $xml = '<value><struct><member><name>foo</name>'
         $xml = '<value><struct><member><name>foo</name>'
-             . '<value/></member></struct></value>';
+             . '<value><string/></value></member></struct></value>';
 
 
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
         $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
                                     Zend_XmlRpc_Value::XML_STRING);
                                     Zend_XmlRpc_Value::XML_STRING);
@@ -516,28 +565,30 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('struct', $val);
         $this->assertXmlRpcType('struct', $val);
         $this->assertEquals('struct', $val->getType());
         $this->assertEquals('struct', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
-    public function testMarshallingStructWithMultibyteValueFromXmlRpcRetainsMultibyteValue()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshallingStructWithMultibyteValueFromXmlRpcRetainsMultibyteValue(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = array('foo' => 'ß');
         $native = array('foo' => 'ß');
-        $xml = '<value><struct><member><name>foo</name>'
-             . '<value><string>&#xDF;</string></value></member></struct></value>';
+        $xmlDecl = '<?xml version="1.0" encoding="UTF-8"?>';
+        $xml = '<value><struct><member><name>foo</name><value><string>ß</string></value></member></struct></value>';
 
 
-        $val = Zend_XmlRpc_Value::getXmlRpcValue($xml,
+        $val = Zend_XmlRpc_Value::getXmlRpcValue($xmlDecl . $xml,
                                     Zend_XmlRpc_Value::XML_STRING);
                                     Zend_XmlRpc_Value::XML_STRING);
 
 
         $this->assertXmlRpcType('struct', $val);
         $this->assertXmlRpcType('struct', $val);
         $this->assertEquals('struct', $val->getType());
         $this->assertEquals('struct', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
 
 
         $val = Zend_XmlRpc_Value::getXmlRpcValue($native, Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT);
         $val = Zend_XmlRpc_Value::getXmlRpcValue($native, Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT);
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertSame($xml . "\n", $val->saveXML());
+        $this->assertSame(trim($xml), trim($val->saveXml()));
     }
     }
 
 
     // DateTime
     // DateTime
@@ -586,8 +637,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, strtotime($val->getValue()));
         $this->assertSame($native, strtotime($val->getValue()));
     }
     }
 
 
-    public function testMarshalDateTimeFromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalDateTimeFromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $iso8601 = '1997-07-16T19:20+01:00';
         $iso8601 = '1997-07-16T19:20+01:00';
         $xml = "<value><dateTime.iso8601>$iso8601</dateTime.iso8601></value>";
         $xml = "<value><dateTime.iso8601>$iso8601</dateTime.iso8601></value>";
 
 
@@ -597,8 +652,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('dateTime', $val);
         $this->assertXmlRpcType('dateTime', $val);
         $this->assertEquals('dateTime.iso8601', $val->getType());
         $this->assertEquals('dateTime.iso8601', $val->getType());
         $this->assertSame(strtotime($iso8601), strtotime($val->getValue()));
         $this->assertSame(strtotime($iso8601), strtotime($val->getValue()));
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     // Base64
     // Base64
@@ -613,8 +667,12 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
     }
     }
 
 
-    public function testMarshalBase64FromXmlRpc()
+    /**
+     * @dataProvider Zend_XmlRpc_TestProvider::provideGenerators
+     */
+    public function testMarshalBase64FromXmlRpc(Zend_XmlRpc_Generator_Abstract $generator)
     {
     {
+        Zend_XmlRpc_Value::setGenerator($generator);
         $native = 'foo';
         $native = 'foo';
         $xml = '<value><base64>' .base64_encode($native). '</base64></value>';
         $xml = '<value><base64>' .base64_encode($native). '</base64></value>';
 
 
@@ -624,8 +682,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
         $this->assertXmlRpcType('base64', $val);
         $this->assertXmlRpcType('base64', $val);
         $this->assertEquals('base64', $val->getType());
         $this->assertEquals('base64', $val->getType());
         $this->assertSame($native, $val->getValue());
         $this->assertSame($native, $val->getValue());
-        $this->assertType('DomElement', $val->getAsDOM());
-        $this->assertEquals($this->wrapXml($xml), $val->saveXML());
+        $this->assertEquals($this->wrapXml($xml), $val->saveXml());
     }
     }
 
 
     public function testXmlRpcValueBase64GeneratedXmlContainsBase64EncodedText()
     public function testXmlRpcValueBase64GeneratedXmlContainsBase64EncodedText()
@@ -635,7 +692,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
                                     Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64);
                                     Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64);
 
 
         $this->assertXmlRpcType('base64', $val);
         $this->assertXmlRpcType('base64', $val);
-        $xml = $val->saveXML();
+        $xml = $val->saveXml();
         $encoded = base64_encode($native);
         $encoded = base64_encode($native);
         $this->assertContains($encoded, $xml);
         $this->assertContains($encoded, $xml);
     }
     }
@@ -678,7 +735,7 @@ class Zend_XmlRpc_ValueTest extends PHPUnit_Framework_TestCase
 
 
     public function wrapXml($xml)
     public function wrapXml($xml)
     {
     {
-        return "<?xml version=\"1.0\"?>\n$xml\n";
+        return $xml . "\n";
     }
     }
 }
 }