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