/** * @param DomDocument $dom * @param $data * @param DomDocument $parent */ private function createNodes($dom, $data, &$parent) { switch (gettype($data)) { case 'string': case 'integer': case 'double': $parent->appendChild($dom->createTextNode($data)); break; case 'boolean': switch ($data) { case true: $value = 'true'; break; case false: $value = 'false'; break; } $parent->appendChild($dom->createTextNode($value)); break; case 'object': case 'array': foreach ($data as $key => $value) { if (is_object($value) and $value instanceof DOMDocument and !empty($value->firstChild)) { $node = $dom->importNode($value->firstChild, true); $parent->appendChild($node); } else { $attributes = null; // SimpleXMLElements can contain key with @attribute as the key name // which indicates an associated array that should be applied to the xml element if (is_object($value) and $value instanceof SimpleXMLElement) { $attributes = $value->attributes(); $value = (array) $value; } // don't emit @attribute as an element of it's own if ($key[0] !== '@') { if (gettype($value) == 'array' and !is_numeric($key)) { $child = $parent->appendChild($dom->createElement($key)); if ($attributes) { foreach ($attributes as $attrKey => $attrValue) { $child->setAttribute($attrKey, $attrValue); } } $this->createNodes($dom, $value, $child); } else { if (is_numeric($key)) { $key = self::DEFAULT_XML_NODE; } $child = $parent->appendChild($dom->createElement($key)); if ($attributes) { foreach ($attributes as $attrKey => $attrValue) { $child->setAttribute($attrKey, $attrValue); } } $this->createNodes($dom, $value, $child); } } else { $parent->setAttribute(substr($key, 1), $value); } } } break; } }