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