/** * Get content (the default). * * @param string encoding * @param var namespaces * @return var data */ public function getContent($encoding = null, $namespaces = null) { $ret = parent::getContent(); @(list($ns, $t) = explode(':', @$this->getAttribute($namespaces[XMLNS_XSI] . ':type'))); switch (strtolower($t)) { case 'base64': case 'base64binary': return new SOAPBase64Binary($ret, $encoded = true); break; case 'hexbinary': return new SOAPHexBinary($ret, $encoded = true); break; case 'boolean': return 0 == strncasecmp('true', $ret, 4) || 0 == strncasecmp('1', $ret, 1) ? true : false; case 'long': case 'int': $t = 'integer'; break; case 'decimal': case 'float': case 'double': $t = 'double'; break; case 'date': case 'datetime': // ISO 8601: http://www.w3.org/TR/xmlschema-2/#ISO8601 http://www.w3.org/TR/xmlschema-2/#dateTime return new \util\Date($ret); break; default: $t = 'string'; } // Decode if necessary $ret = iconv($encoding, \xp::ENCODING, $ret); // Set type settype($ret, $t); return $ret; }
/** * Recursively deserialize data for the given node. * * @param xml.Node node * @return var * @throws lang.IllegalArgumentException if the data cannot be deserialized * @throws lang.ClassNotFoundException in case a XP object's class could not be loaded * @throws xml.XMLFormatException */ protected function _unmarshall(Node $node) { // Simple form: If no subnode indicating the type exists, the type // is string, e.g. <value>Test</value> if (!$node->hasChildren()) { return (string) $node->getContent(); } // Long form - with subnode, the type is derived from the node's name, // e.g. <value><string>Test</string></value>. $c = $node->nodeAt(0); switch ($c->getName()) { case 'struct': $ret = []; foreach ($c->getChildren() as $child) { $data = []; $data[$child->nodeAt(0)->getName()] = $child->nodeAt(0); $data[$child->nodeAt(1)->getName()] = $child->nodeAt(1); $ret[$data['name']->getContent()] = $this->_unmarshall($data['value']); unset($data); } if (!isset($ret['__xp_class'])) { return $ret; } $class = XPClass::forName($ret['__xp_class']); $instance = $class->newInstance(); foreach ($ret as $name => $value) { if (!$class->hasField($name)) { continue; } $field = $class->getField($name); if ($field->getModifiers() & MODIFIER_STATIC) { continue; } $class->getField($name)->setAccessible(true)->set($instance, $value); } return $instance; case 'array': $ret = []; foreach ($c->nodeAt(0)->getChildren() as $child) { $ret[] = $this->_unmarshall($child); } return $ret; case 'int': case 'i4': return (int) $c->getContent(); case 'double': return (double) $c->getContent(); case 'boolean': return (bool) $c->getContent(); case 'string': return (string) $c->getContent(); case 'dateTime.iso8601': return new Date($c->getContent()); case 'nil': return null; case 'base64': return new Bytes(base64_decode($c->getContent())); default: throw new \lang\IllegalArgumentException('Could not decode node as its type is not supported: ' . $c->getName()); } }