public function objectToDomElement($obj, DomNode $node, DomDocument $doc)
    {
        if (isset($obj->__cdata)) {
            $node->appendChild($doc->createCDATASection($obj->__cdata));
        }

        foreach ($obj as $key => &$val) {
            if (in_array($key, array('__attr', '__cdata'), true)) {
                continue;
            } elseif (is_array($val) || $val instanceof ArrayAccess) {
                foreach ($val as $k => &$v) {
                    $e = $doc->createElement($key);

                    if (is_object($v)) {
                        $this->objectToDomElement($v, $e, $doc);
                    } elseif (is_string($v) && !empty($v)) {
                        $e->appendChild($doc->createTextNode((string) $v));
                    }

                    if (isset($obj->__attr) && isset($obj->__attr[$key][$k])) {
                        foreach ((array) $obj->__attr[$key][$k] as $k2 => $v2) {
                            $e->setAttribute($k2, (string) $v2);
                        }
                    }

                    $node->appendChild($e);
                }
                continue;
            } elseif (is_object($val)) {
                $e = $this->objectToDomElement($val, $doc->createElement($key), $doc);
            } elseif ($val !== null) {
                $e = $doc->createElement($key);
                $e->appendChild($doc->createTextNode($val));
            } else {
                continue;
            }

            if (isset($obj->__attr) && isset($obj->__attr[$key])) {
                foreach ((array) $obj->__attr[$key] as $k => $v) {
                    $e->setAttribute($k, (string) $v);
                }
            }

            $node->appendChild($e);
        }

        return $node;
    }