📄 class.soap_parser.php
字号:
<?php
class soap_parser extends nusoap_base
{
var $xml = "";
var $xml_encoding = "";
var $method = "";
var $root_struct = "";
var $root_struct_name = "";
var $root_struct_namespace = "";
var $root_header = "";
var $document = "";
var $status = "";
var $position = 0;
var $depth = 0;
var $default_namespace = "";
var $namespaces = array( );
var $message = array( );
var $parent = "";
var $fault = false;
var $fault_code = "";
var $fault_str = "";
var $fault_detail = "";
var $depth_array = array( );
var $debug_flag = true;
var $soapresponse = NULL;
var $responseHeaders = "";
var $body_position = 0;
var $ids = array( );
var $multirefs = array( );
var $decode_utf8 = true;
function soap_parser( $xml, $encoding = "UTF-8", $method = "", $decode_utf8 = true )
{
$this->xml = $xml;
$this->xml_encoding = $encoding;
$this->method = $method;
$this->decode_utf8 = $decode_utf8;
if ( !empty( $xml ) )
{
$this->debug( "Entering soap_parser(), length=".strlen( $xml ).", encoding=".$encoding );
$this->parser = xml_parser_create( $this->xml_encoding );
xml_parser_set_option( $this->parser, XML_OPTION_CASE_FOLDING, 0 );
xml_parser_set_option( $this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding );
xml_set_object( $this->parser, $this );
xml_set_element_handler( $this->parser, "start_element", "end_element" );
xml_set_character_data_handler( $this->parser, "character_data" );
if ( !xml_parse( $this->parser, $xml, true ) )
{
$err = sprintf( "XML error parsing SOAP payload on line %d: %s", xml_get_current_line_number( $this->parser ), xml_error_string( xml_get_error_code( $this->parser ) ) );
$this->debug( $err );
$this->debug( "XML payload:\n".$xml );
$this->seterror( $err );
}
else
{
$this->debug( "parsed successfully, found root struct: ".$this->root_struct." of name ".$this->root_struct_name );
$this->soapresponse = $this->message[$this->root_struct]['result'];
if ( 0 < sizeof( $this->multirefs ) )
{
foreach ( $this->multirefs as $id => $hrefs )
{
$this->debug( "resolving multirefs for id: ".$id );
$idVal = $this->buildval( $this->ids[$id] );
foreach ( $hrefs as $refPos => $ref )
{
$this->debug( "resolving href at pos ".$refPos );
$this->multirefs[$id][$refPos] = $idVal;
}
}
}
}
xml_parser_free( $this->parser );
}
else
{
$this->debug( "xml was empty, didn't parse!" );
$this->seterror( "xml was empty, didn't parse!" );
}
}
function start_element( $parser, $name, $attrs )
{
$pos = $this->position++;
$this->message[$pos] = array(
"pos" => $pos,
"children" => "",
"cdata" => ""
);
$this->message[$pos]['depth'] = $this->depth++;
if ( $pos != 0 )
{
$this->message[$this->parent]['children'] .= "|".$pos;
}
$this->message[$pos]['parent'] = $this->parent;
$this->parent = $pos;
$this->depth_array[$this->depth] = $pos;
if ( strpos( $name, ":" ) )
{
$prefix = substr( $name, 0, strpos( $name, ":" ) );
$name = substr( strstr( $name, ":" ), 1 );
}
if ( $name == "Envelope" )
{
$this->status = "envelope";
}
else if ( $name == "Header" )
{
$this->root_header = $pos;
$this->status = "header";
}
else if ( $name == "Body" )
{
$this->status = "body";
$this->body_position = $pos;
}
else if ( $this->status == "body" && $pos == $this->body_position + 1 )
{
$this->status = "method";
$this->root_struct_name = $name;
$this->root_struct = $pos;
$this->message[$pos]['type'] = "struct";
$this->debug( "found root struct {$this->root_struct_name}, pos {$this->root_struct}" );
}
$this->message[$pos]['status'] = $this->status;
$this->message[$pos]['name'] = htmlspecialchars( $name );
$this->message[$pos]['attrs'] = $attrs;
$attstr = "";
foreach ( $attrs as $key => $value )
{
$key_prefix = $this->getprefix( $key );
$key_localpart = $this->getlocalpart( $key );
if ( $key_prefix == "xmlns" )
{
if ( ereg( "^http://www.w3.org/[0-9]{4}/XMLSchema\$", $value ) )
{
$this->XMLSchemaVersion = $value;
$this->namespaces['xsd'] = $this->XMLSchemaVersion;
$this->namespaces['xsi'] = $this->XMLSchemaVersion."-instance";
}
$this->namespaces[$key_localpart] = $value;
if ( $name == $this->root_struct_name )
{
$this->methodNamespace = $value;
}
}
else if ( $key_localpart == "type" )
{
$value_prefix = $this->getprefix( $value );
$value_localpart = $this->getlocalpart( $value );
$this->message[$pos]['type'] = $value_localpart;
$this->message[$pos]['typePrefix'] = $value_prefix;
if ( isset( $this->namespaces[$value_prefix] ) )
{
$this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
}
else if ( isset( $attrs["xmlns:".$value_prefix] ) )
{
$this->message[$pos]['type_namespace'] = $attrs["xmlns:".$value_prefix];
}
}
else if ( $key_localpart == "arrayType" )
{
$this->message[$pos]['type'] = "array";
$expr = "([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\\[([0-9]+),?([0-9]*)\\]";
if ( ereg( $expr, $value, $regs ) )
{
$this->message[$pos]['typePrefix'] = $regs[1];
$this->message[$pos]['arrayTypePrefix'] = $regs[1];
if ( isset( $this->namespaces[$regs[1]] ) )
{
$this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
}
else if ( isset( $attrs["xmlns:".$regs[1]] ) )
{
$this->message[$pos]['arrayTypeNamespace'] = $attrs["xmlns:".$regs[1]];
}
$this->message[$pos]['arrayType'] = $regs[2];
$this->message[$pos]['arraySize'] = $regs[3];
$this->message[$pos]['arrayCols'] = $regs[4];
}
}
if ( $key == "id" )
{
$this->ids[$value] = $pos;
}
if ( $key_localpart == "root" && $value == 1 )
{
$this->status = "method";
$this->root_struct_name = $name;
$this->root_struct = $pos;
$this->debug( "found root struct {$this->root_struct_name}, pos {$pos}" );
}
$attstr .= " {$key}=\"{$value}\"";
}
if ( isset( $prefix ) )
{
$this->message[$pos]['namespace'] = $this->namespaces[$prefix];
$this->default_namespace = $this->namespaces[$prefix];
}
else
{
$this->message[$pos]['namespace'] = $this->default_namespace;
}
if ( $this->status == "header" )
{
if ( $this->root_header != $pos )
{
$this->responseHeaders .= "<".( isset( $prefix ) ? $prefix.":" : "" )."{$name}{$attstr}>";
}
}
else if ( $this->root_struct_name != "" )
{
$this->document .= "<".( isset( $prefix ) ? $prefix.":" : "" )."{$name}{$attstr}>";
}
}
function end_element( $parser, $name )
{
$pos = $this->depth_array[$this->depth--];
if ( strpos( $name, ":" ) )
{
$prefix = substr( $name, 0, strpos( $name, ":" ) );
$name = substr( strstr( $name, ":" ), 1 );
}
if ( isset( $this->body_position ) && $this->body_position < $pos )
{
if ( isset( $this->message[$pos]['attrs']['href'] ) )
{
$id = substr( $this->message[$pos]['attrs']['href'], 1 );
$this->multirefs[$id][$pos] = "placeholder";
$this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
}
else if ( $this->message[$pos]['children'] != "" )
{
if ( !isset( $this->message[$pos]['result'] ) )
{
$this->message[$pos]['result'] = $this->buildval( $pos );
}
}
else if ( isset( $this->message[$pos]['type'] ) )
{
$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'] : "" );
}
else
{
$parent = $this->message[$pos]['parent'];
if ( isset( $this->message[$parent]['type'] ) && $this->message[$parent]['type'] == "array" && isset( $this->message[$parent]['arrayType'] ) )
{
$this->message[$pos]['result'] = $this->decodesimple( $this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset( $this->message[$parent]['arrayTypeNamespace'] ) ? $this->message[$parent]['arrayTypeNamespace'] : "" );
}
else
{
$this->message[$pos]['result'] = $this->message[$pos]['cdata'];
}
}
}
if ( $this->status == "header" )
{
if ( $this->root_header != $pos )
{
$this->responseHeaders .= "</".( isset( $prefix ) ? $prefix.":" : "" )."{$name}>";
}
}
else if ( $this->root_struct <= $pos )
{
$this->document .= "</".( isset( $prefix ) ? $prefix.":" : "" )."{$name}>";
}
if ( $pos == $this->root_struct )
{
$this->status = "body";
$this->root_struct_namespace = $this->message[$pos]['namespace'];
}
else if ( $name == "Body" )
{
$this->status = "envelope";
}
else if ( $name == "Header" )
{
$this->status = "envelope";
}
else if ( $name == "Envelope" )
{
}
$this->parent = $this->message[$pos]['parent'];
}
function character_data( $parser, $data )
{
$pos = $this->depth_array[$this->depth];
if ( $this->xml_encoding == "UTF-8" )
{
if ( $this->decode_utf8 )
{
$data = utf8_decode( $data );
}
}
$this->message[$pos]['cdata'] .= $data;
if ( $this->status == "header" )
{
$this->responseHeaders .= $data;
}
else
{
$this->document .= $data;
}
}
function get_response( )
{
return $this->soapresponse;
}
function getheaders( )
{
return $this->responseHeaders;
}
function decode_entities( $text )
{
foreach ( $this->entities as $entity => $encoded )
{
$text = str_replace( $encoded, $entity, $text );
}
return $text;
}
function decodesimple( $value, $type, $typens )
{
if ( !isset( $type ) || $type == "string" || $type == "long" || $type == "unsignedLong" )
{
return ( boolean )$value;
}
if ( $type == "int" || $type == "integer" || $type == "short" || $type == "byte" )
{
return ( integer )$value;
}
if ( $type == "float" || $type == "double" || $type == "decimal" )
{
return ( double )$value;
}
if ( $type == "boolean" )
{
if ( strtolower( $value ) == "false" || strtolower( $value ) == "f" )
{
return false;
}
return ( string )$value;
}
if ( $type == "base64" || $type == "base64Binary" )
{
return base64_decode( $value );
}
if ( $type == "nonPositiveInteger" || $type == "negativeInteger" || $type == "nonNegativeInteger" || $type == "positiveInteger" || $type == "unsignedInt" || $type == "unsignedShort" || $type == "unsignedByte" )
{
return ( integer )$value;
}
return ( boolean )$value;
}
function buildval( $pos )
{
if ( !isset( $this->message[$pos]['type'] ) )
{
$this->message[$pos]['type'] = "";
}
$this->debug( "inside buildVal() for ".$this->message[$pos]['name']."(pos {$pos}) of type ".$this->message[$pos]['type'] );
if ( $this->message[$pos]['children'] != "" )
{
$children = explode( "|", $this->message[$pos]['children'] );
array_shift( $children );
if ( isset( $this->message[$pos]['arrayCols'] ) && $this->message[$pos]['arrayCols'] != "" )
{
$r = 0;
$c = 0;
foreach ( $children as $child_pos )
{
$this->debug( "got an MD array element: {$r}, {$c}" );
$params[$r][] = $this->message[$child_pos]['result'];
$c++;
if ( $c == $this->message[$pos]['arrayCols'] )
{
$c = 0;
$r++;
}
}
}
else if ( $this->message[$pos]['type'] == "array" || $this->message[$pos]['type'] == "Array" )
{
$this->debug( "adding array ".$this->message[$pos]['name'] );
foreach ( $children as $child_pos )
{
$params[] =& $this->message[$child_pos]['result'];
}
}
else
{
if ( $this->message[$pos]['type'] == "Map" && $this->message[$pos]['type_namespace'] == "http://xml.apache.org/xml-soap" )
{
foreach ( $children as $child_pos )
{
$kv = explode( "|", $this->message[$child_pos]['children'] );
$params[$this->message[$kv[1]]['result']] =& $this->message[$kv[2]]['result'];
}
}
else
{
if ( $this->message[$pos]['type'] == "Vector" && $this->message[$pos]['type_namespace'] == "http://xml.apache.org/xml-soap" )
{
$notstruct = 1;
}
else
{
foreach ( $children as $child_pos )
{
if ( isset( $keys ) && isset( $keys[$this->message[$child_pos]['name']] ) )
{
$notstruct = 1;
break;
}
$keys[$this->message[$child_pos]['name']] = 1;
}
}
foreach ( $children as $child_pos )
{
if ( isset( $notstruct ) )
{
$params[] =& $this->message[$child_pos]['result'];
}
else if ( isset( $params[$this->message[$child_pos]['name']] ) )
{
if ( !is_array( $params[$this->message[$child_pos]['name']] ) )
{
$params[$this->message[$child_pos]['name']] = array(
$params[$this->message[$child_pos]['name']]
);
}
$params[$this->message[$child_pos]['name']][] =& $this->message[$child_pos]['result'];
}
else
{
$params[$this->message[$child_pos]['name']] =& $this->message[$child_pos]['result'];
}
}
}
}
return is_array( $params ) ? $params : array( );
}
else
{
$this->debug( "no children" );
if ( strpos( $this->message[$pos]['cdata'], "&" ) )
{
return strtr( $this->message[$pos]['cdata'], array_flip( $this->entities ) );
}
else
{
return $this->message[$pos]['cdata'];
}
}
}
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -