1<?php 2 3 4 5 6/** 7* 8* nusoap_parser class parses SOAP XML messages into native PHP values 9* 10* @author Dietrich Ayala <dietrich@ganx4.com> 11* @author Scott Nichol <snichol@users.sourceforge.net> 12* @version $Id: class.soap_parser.php,v 1.40 2007/04/17 16:34:03 snichol Exp $ 13* @access public 14*/ 15class nusoap_parser extends nusoap_base { 16 17 var $xml = ''; 18 var $xml_encoding = ''; 19 var $method = ''; 20 var $root_struct = ''; 21 var $root_struct_name = ''; 22 var $root_struct_namespace = ''; 23 var $root_header = ''; 24 var $document = ''; // incoming SOAP body (text) 25 // determines where in the message we are (envelope,header,body,method) 26 var $status = ''; 27 var $position = 0; 28 var $depth = 0; 29 var $default_namespace = ''; 30 var $namespaces = array(); 31 var $message = array(); 32 var $parent = ''; 33 var $fault = false; 34 var $fault_code = ''; 35 var $fault_str = ''; 36 var $fault_detail = ''; 37 var $depth_array = array(); 38 var $debug_flag = true; 39 var $soapresponse = NULL; // parsed SOAP Body 40 var $soapheader = NULL; // parsed SOAP Header 41 var $responseHeaders = ''; // incoming SOAP headers (text) 42 var $body_position = 0; 43 // for multiref parsing: 44 // array of id => pos 45 var $ids = array(); 46 // array of id => hrefs => pos 47 var $multirefs = array(); 48 // toggle for auto-decoding element content 49 var $decode_utf8 = true; 50 51 /** 52 * constructor that actually does the parsing 53 * 54 * @param string $xml SOAP message 55 * @param string $encoding character encoding scheme of message 56 * @param string $method method for which XML is parsed (unused?) 57 * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1 58 * @access public 59 */ 60 function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){ 61 parent::nusoap_base(); 62 $this->xml = $xml; 63 $this->xml_encoding = $encoding; 64 $this->method = $method; 65 $this->decode_utf8 = $decode_utf8; 66 67 // Check whether content has been read. 68 if(!empty($xml)){ 69 // Check XML encoding 70 $pos_xml = strpos($xml, '<?xml'); 71 if ($pos_xml !== FALSE) { 72 $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1); 73 if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) { 74 $xml_encoding = $res[1]; 75 if (strtoupper($xml_encoding) != $encoding) { 76 $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'"; 77 $this->debug($err); 78 if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') { 79 $this->setError($err); 80 return; 81 } 82 // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed 83 } else { 84 $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration'); 85 } 86 } else { 87 $this->debug('No encoding specified in XML declaration'); 88 } 89 } else { 90 $this->debug('No XML declaration'); 91 } 92 $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding); 93 // Create an XML parser - why not xml_parser_create_ns? 94 $this->parser = xml_parser_create($this->xml_encoding); 95 // Set the options for parsing the XML data. 96 //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); 97 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 98 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding); 99 // Set the object for the parser. 100 xml_set_object($this->parser, $this); 101 // Set the element handlers for the parser. 102 xml_set_element_handler($this->parser, 'start_element','end_element'); 103 xml_set_character_data_handler($this->parser,'character_data'); 104 105 // Parse the XML file. 106 if(!xml_parse($this->parser,$xml,true)){ 107 // Display an error message. 108 $err = sprintf('XML error parsing SOAP payload on line %d: %s', 109 xml_get_current_line_number($this->parser), 110 xml_error_string(xml_get_error_code($this->parser))); 111 $this->debug($err); 112 $this->debug("XML payload:\n" . $xml); 113 $this->setError($err); 114 } else { 115 $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name); 116 // get final value 117 $this->soapresponse = $this->message[$this->root_struct]['result']; 118 // get header value 119 if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){ 120 $this->soapheader = $this->message[$this->root_header]['result']; 121 } 122 // resolve hrefs/ids 123 if(sizeof($this->multirefs) > 0){ 124 foreach($this->multirefs as $id => $hrefs){ 125 $this->debug('resolving multirefs for id: '.$id); 126 $idVal = $this->buildVal($this->ids[$id]); 127 if (is_array($idVal) && isset($idVal['!id'])) { 128 unset($idVal['!id']); 129 } 130 foreach($hrefs as $refPos => $ref){ 131 $this->debug('resolving href at pos '.$refPos); 132 $this->multirefs[$id][$refPos] = $idVal; 133 } 134 } 135 } 136 } 137 xml_parser_free($this->parser); 138 } else { 139 $this->debug('xml was empty, didn\'t parse!'); 140 $this->setError('xml was empty, didn\'t parse!'); 141 } 142 } 143 144 /** 145 * start-element handler 146 * 147 * @param resource $parser XML parser object 148 * @param string $name element name 149 * @param array $attrs associative array of attributes 150 * @access private 151 */ 152 function start_element($parser, $name, $attrs) { 153 // position in a total number of elements, starting from 0 154 // update class level pos 155 $pos = $this->position++; 156 // and set mine 157 $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>''); 158 // depth = how many levels removed from root? 159 // set mine as current global depth and increment global depth value 160 $this->message[$pos]['depth'] = $this->depth++; 161 162 // else add self as child to whoever the current parent is 163 if($pos != 0){ 164 $this->message[$this->parent]['children'] .= '|'.$pos; 165 } 166 // set my parent 167 $this->message[$pos]['parent'] = $this->parent; 168 // set self as current parent 169 $this->parent = $pos; 170 // set self as current value for this depth 171 $this->depth_array[$this->depth] = $pos; 172 // get element prefix 173 if(strpos($name,':')){ 174 // get ns prefix 175 $prefix = substr($name,0,strpos($name,':')); 176 // get unqualified name 177 $name = substr(strstr($name,':'),1); 178 } 179 // set status 180 if($name == 'Envelope'){ 181 $this->status = 'envelope'; 182 } elseif($name == 'Header' && $this->status = 'envelope'){ 183 $this->root_header = $pos; 184 $this->status = 'header'; 185 } elseif($name == 'Body' && $this->status = 'envelope'){ 186 $this->status = 'body'; 187 $this->body_position = $pos; 188 // set method 189 } elseif($this->status == 'body' && $pos == ($this->body_position+1)){ 190 $this->status = 'method'; 191 $this->root_struct_name = $name; 192 $this->root_struct = $pos; 193 $this->message[$pos]['type'] = 'struct'; 194 $this->debug("found root struct $this->root_struct_name, pos $this->root_struct"); 195 } 196 // set my status 197 $this->message[$pos]['status'] = $this->status; 198 // set name 199 $this->message[$pos]['name'] = htmlspecialchars($name); 200 // set attrs 201 $this->message[$pos]['attrs'] = $attrs; 202 203 // loop through atts, logging ns and type declarations 204 $attstr = ''; 205 foreach($attrs as $key => $value){ 206 $key_prefix = $this->getPrefix($key); 207 $key_localpart = $this->getLocalPart($key); 208 // if ns declarations, add to class level array of valid namespaces 209 if($key_prefix == 'xmlns'){ 210 if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){ 211 $this->XMLSchemaVersion = $value; 212 $this->namespaces['xsd'] = $this->XMLSchemaVersion; 213 $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance'; 214 } 215 $this->namespaces[$key_localpart] = $value; 216 // set method namespace 217 if($name == $this->root_struct_name){ 218 $this->methodNamespace = $value; 219 } 220 // if it's a type declaration, set type 221 } elseif($key_localpart == 'type'){ 222 if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') { 223 // do nothing: already processed arrayType 224 } else { 225 $value_prefix = $this->getPrefix($value); 226 $value_localpart = $this->getLocalPart($value); 227 $this->message[$pos]['type'] = $value_localpart; 228 $this->message[$pos]['typePrefix'] = $value_prefix; 229 if(isset($this->namespaces[$value_prefix])){ 230 $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix]; 231 } else if(isset($attrs['xmlns:'.$value_prefix])) { 232 $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix]; 233 } 234 // should do something here with the namespace of specified type? 235 } 236 } elseif($key_localpart == 'arrayType'){ 237 $this->message[$pos]['type'] = 'array'; 238 /* do arrayType ereg here 239 [1] arrayTypeValue ::= atype asize 240 [2] atype ::= QName rank* 241 [3] rank ::= '[' (',')* ']' 242 [4] asize ::= '[' length~ ']' 243 [5] length ::= nextDimension* Digit+ 244 [6] nextDimension ::= Digit+ ',' 245 */ 246 $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]'; 247 if(ereg($expr,$value,$regs)){ 248 $this->message[$pos]['typePrefix'] = $regs[1]; 249 $this->message[$pos]['arrayTypePrefix'] = $regs[1]; 250 if (isset($this->namespaces[$regs[1]])) { 251 $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]]; 252 } else if (isset($attrs['xmlns:'.$regs[1]])) { 253 $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]]; 254 } 255 $this->message[$pos]['arrayType'] = $regs[2]; 256 $this->message[$pos]['arraySize'] = $regs[3]; 257 $this->message[$pos]['arrayCols'] = $regs[4]; 258 } 259 // specifies nil value (or not) 260 } elseif ($key_localpart == 'nil'){ 261 $this->message[$pos]['nil'] = ($value == 'true' || $value == '1'); 262 // some other attribute 263 } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') { 264 $this->message[$pos]['xattrs']['!' . $key] = $value; 265 } 266 267 if ($key == 'xmlns') { 268 $this->default_namespace = $value; 269 } 270 // log id 271 if($key == 'id'){ 272 $this->ids[$value] = $pos; 273 } 274 // root 275 if($key_localpart == 'root' && $value == 1){ 276 $this->status = 'method'; 277 $this->root_struct_name = $name; 278 $this->root_struct = $pos; 279 $this->debug("found root struct $this->root_struct_name, pos $pos"); 280 } 281 // for doclit 282 $attstr .= " $key=\"$value\""; 283 } 284 // get namespace - must be done after namespace atts are processed 285 if(isset($prefix)){ 286 $this->message[$pos]['namespace'] = $this->namespaces[$prefix]; 287 $this->default_namespace = $this->namespaces[$prefix]; 288 } else { 289 $this->message[$pos]['namespace'] = $this->default_namespace; 290 } 291 if($this->status == 'header'){ 292 if ($this->root_header != $pos) { 293 $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; 294 } 295 } elseif($this->root_struct_name != ''){ 296 $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>"; 297 } 298 } 299 300 /** 301 * end-element handler 302 * 303 * @param resource $parser XML parser object 304 * @param string $name element name 305 * @access private 306 */ 307 function end_element($parser, $name) { 308 // position of current element is equal to the last value left in depth_array for my depth 309 $pos = $this->depth_array[$this->depth--]; 310 311 // get element prefix 312 if(strpos($name,':')){ 313 // get ns prefix 314 $prefix = substr($name,0,strpos($name,':')); 315 // get unqualified name 316 $name = substr(strstr($name,':'),1); 317 } 318 319 // build to native type 320 if(isset($this->body_position) && $pos > $this->body_position){ 321 // deal w/ multirefs 322 if(isset($this->message[$pos]['attrs']['href'])){ 323 // get id 324 $id = substr($this->message[$pos]['attrs']['href'],1); 325 // add placeholder to href array 326 $this->multirefs[$id][$pos] = 'placeholder'; 327 // add set a reference to it as the result value 328 $this->message[$pos]['result'] =& $this->multirefs[$id][$pos]; 329 // build complexType values 330 } elseif($this->message[$pos]['children'] != ''){ 331 // if result has already been generated (struct/array) 332 if(!isset($this->message[$pos]['result'])){ 333 $this->message[$pos]['result'] = $this->buildVal($pos); 334 } 335 // build complexType values of attributes and possibly simpleContent 336 } elseif (isset($this->message[$pos]['xattrs'])) { 337 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { 338 $this->message[$pos]['xattrs']['!'] = null; 339 } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { 340 if (isset($this->message[$pos]['type'])) { 341 $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); 342 } else { 343 $parent = $this->message[$pos]['parent']; 344 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { 345 $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); 346 } else { 347 $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata']; 348 } 349 } 350 } 351 $this->message[$pos]['result'] = $this->message[$pos]['xattrs']; 352 // set value of simpleType (or nil complexType) 353 } else { 354 //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']); 355 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) { 356 $this->message[$pos]['xattrs']['!'] = null; 357 } elseif (isset($this->message[$pos]['type'])) { 358 $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); 359 } else { 360 $parent = $this->message[$pos]['parent']; 361 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { 362 $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); 363 } else { 364 $this->message[$pos]['result'] = $this->message[$pos]['cdata']; 365 } 366 } 367 368 /* add value to parent's result, if parent is struct/array 369 $parent = $this->message[$pos]['parent']; 370 if($this->message[$parent]['type'] != 'map'){ 371 if(strtolower($this->message[$parent]['type']) == 'array'){ 372 $this->message[$parent]['result'][] = $this->message[$pos]['result']; 373 } else { 374 $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result']; 375 } 376 } 377 */ 378 } 379 } 380 381 // for doclit 382 if($this->status == 'header'){ 383 if ($this->root_header != $pos) { 384 $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; 385 } 386 } elseif($pos >= $this->root_struct){ 387 $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>"; 388 } 389 // switch status 390 if($pos == $this->root_struct){ 391 $this->status = 'body'; 392 $this->root_struct_namespace = $this->message[$pos]['namespace']; 393 } elseif($name == 'Body'){ 394 $this->status = 'envelope'; 395 } elseif($name == 'Header'){ 396 $this->status = 'envelope'; 397 } elseif($name == 'Envelope'){ 398 // 399 } 400 // set parent back to my parent 401 $this->parent = $this->message[$pos]['parent']; 402 } 403 404 /** 405 * element content handler 406 * 407 * @param resource $parser XML parser object 408 * @param string $data element content 409 * @access private 410 */ 411 function character_data($parser, $data){ 412 $pos = $this->depth_array[$this->depth]; 413 if ($this->xml_encoding=='UTF-8'){ 414 // TODO: add an option to disable this for folks who want 415 // raw UTF-8 that, e.g., might not map to iso-8859-1 416 // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1"); 417 if($this->decode_utf8){ 418 $data = utf8_decode($data); 419 } 420 } 421 $this->message[$pos]['cdata'] .= $data; 422 // for doclit 423 if($this->status == 'header'){ 424 $this->responseHeaders .= $data; 425 } else { 426 $this->document .= $data; 427 } 428 } 429 430 /** 431 * get the parsed message (SOAP Body) 432 * 433 * @return mixed 434 * @access public 435 * @deprecated use get_soapbody instead 436 */ 437 function get_response(){ 438 return $this->soapresponse; 439 } 440 441 /** 442 * get the parsed SOAP Body (NULL if there was none) 443 * 444 * @return mixed 445 * @access public 446 */ 447 function get_soapbody(){ 448 return $this->soapresponse; 449 } 450 451 /** 452 * get the parsed SOAP Header (NULL if there was none) 453 * 454 * @return mixed 455 * @access public 456 */ 457 function get_soapheader(){ 458 return $this->soapheader; 459 } 460 461 /** 462 * get the unparsed SOAP Header 463 * 464 * @return string XML or empty if no Header 465 * @access public 466 */ 467 function getHeaders(){ 468 return $this->responseHeaders; 469 } 470 471 /** 472 * decodes simple types into PHP variables 473 * 474 * @param string $value value to decode 475 * @param string $type XML type to decode 476 * @param string $typens XML type namespace to decode 477 * @return mixed PHP value 478 * @access private 479 */ 480 function decodeSimple($value, $type, $typens) { 481 // TODO: use the namespace! 482 if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') { 483 return (string) $value; 484 } 485 if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') { 486 return (int) $value; 487 } 488 if ($type == 'float' || $type == 'double' || $type == 'decimal') { 489 return (double) $value; 490 } 491 if ($type == 'boolean') { 492 if (strtolower($value) == 'false' || strtolower($value) == 'f') { 493 return false; 494 } 495 return (boolean) $value; 496 } 497 if ($type == 'base64' || $type == 'base64Binary') { 498 $this->debug('Decode base64 value'); 499 return base64_decode($value); 500 } 501 // obscure numeric types 502 if ($type == 'nonPositiveInteger' || $type == 'negativeInteger' 503 || $type == 'nonNegativeInteger' || $type == 'positiveInteger' 504 || $type == 'unsignedInt' 505 || $type == 'unsignedShort' || $type == 'unsignedByte') { 506 return (int) $value; 507 } 508 // bogus: parser treats array with no elements as a simple type 509 if ($type == 'array') { 510 return array(); 511 } 512 // everything else 513 return (string) $value; 514 } 515 516 /** 517 * builds response structures for compound values (arrays/structs) 518 * and scalars 519 * 520 * @param integer $pos position in node tree 521 * @return mixed PHP value 522 * @access private 523 */ 524 function buildVal($pos){ 525 if(!isset($this->message[$pos]['type'])){ 526 $this->message[$pos]['type'] = ''; 527 } 528 $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']); 529 // if there are children... 530 if($this->message[$pos]['children'] != ''){ 531 $this->debug('in buildVal, there are children'); 532 $children = explode('|',$this->message[$pos]['children']); 533 array_shift($children); // knock off empty 534 // md array 535 if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){ 536 $r=0; // rowcount 537 $c=0; // colcount 538 foreach($children as $child_pos){ 539 $this->debug("in buildVal, got an MD array element: $r, $c"); 540 $params[$r][] = $this->message[$child_pos]['result']; 541 $c++; 542 if($c == $this->message[$pos]['arrayCols']){ 543 $c = 0; 544 $r++; 545 } 546 } 547 // array 548 } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){ 549 $this->debug('in buildVal, adding array '.$this->message[$pos]['name']); 550 foreach($children as $child_pos){ 551 $params[] = &$this->message[$child_pos]['result']; 552 } 553 // apache Map type: java hashtable 554 } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){ 555 $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']); 556 foreach($children as $child_pos){ 557 $kv = explode("|",$this->message[$child_pos]['children']); 558 $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result']; 559 } 560 // generic compound type 561 //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') { 562 } else { 563 // Apache Vector type: treat as an array 564 $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']); 565 if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') { 566 $notstruct = 1; 567 } else { 568 $notstruct = 0; 569 } 570 // 571 foreach($children as $child_pos){ 572 if($notstruct){ 573 $params[] = &$this->message[$child_pos]['result']; 574 } else { 575 if (isset($params[$this->message[$child_pos]['name']])) { 576 // de-serialize repeated element name into an array 577 if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) { 578 $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]); 579 } 580 $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result']; 581 } else { 582 $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result']; 583 } 584 } 585 } 586 } 587 if (isset($this->message[$pos]['xattrs'])) { 588 $this->debug('in buildVal, handling attributes'); 589 foreach ($this->message[$pos]['xattrs'] as $n => $v) { 590 $params[$n] = $v; 591 } 592 } 593 // handle simpleContent 594 if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') { 595 $this->debug('in buildVal, handling simpleContent'); 596 if (isset($this->message[$pos]['type'])) { 597 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); 598 } else { 599 $parent = $this->message[$pos]['parent']; 600 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { 601 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); 602 } else { 603 $params['!'] = $this->message[$pos]['cdata']; 604 } 605 } 606 } 607 $ret = is_array($params) ? $params : array(); 608 $this->debug('in buildVal, return:'); 609 $this->appendDebug($this->varDump($ret)); 610 return $ret; 611 } else { 612 $this->debug('in buildVal, no children, building scalar'); 613 $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : ''; 614 if (isset($this->message[$pos]['type'])) { 615 $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : ''); 616 $this->debug("in buildVal, return: $ret"); 617 return $ret; 618 } 619 $parent = $this->message[$pos]['parent']; 620 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) { 621 $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : ''); 622 $this->debug("in buildVal, return: $ret"); 623 return $ret; 624 } 625 $ret = $this->message[$pos]['cdata']; 626 $this->debug("in buildVal, return: $ret"); 627 return $ret; 628 } 629 } 630} 631 632/** 633 * Backward compatibility 634 */ 635class soap_parser extends nusoap_parser { 636} 637 638 639?>