Loading ...
Sorry, an error occurred while loading the content.

Re: [php-objects] web service

Expand Messages
  • abhijit murade
    hi binoy,here with am sending some files which will help you to know working of webservice run these file in php environment and change the wsdl path as per
    Message 1 of 7 , Feb 6, 2008
    • 0 Attachment
      hi binoy,

      here with am sending some files which will help you to know working of
      webservice
      run these file in php environment and change the wsdl path as per
      environment.
      in these i have created WSDL which is required to access any webservice
      as u told client will be .Net, just u have to give web reference and paste
      WSDL url
      in address bar, simply call the method from your applicaion
      hope this will help u

      Regards,
      Abhijit Murade

      On 2/5/08, binoy <binoymvee@...> wrote:
      >
      > Hi Every one,
      > I want to write a web service.
      > server is php and cleint is .net.
      >
      > my requirement is that i want to return product list (all the product or
      > single product -- that depend on the id we are getting from client machine )
      > from an oscommerce site.the client is .net and the server is php.
      >
      > Actually i dont know anything abt the webservices. Can anybody help me.
      >
      >
      >
      >
      >
      > With Regards
      > Binoy.M.V
      >
      >
      > ---------------------------------
      > 5, 50, 500, 5000 - Store N number of mails in your inbox. Click here.
      >
      > [Non-text portions of this message have been removed]
      >
      >
      >



      --
      Thanks & Regards,

      ----------

      <?php

      /*
      $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $

      NuSOAP - Web Services Toolkit for PHP

      Copyright (c) 2002 NuSphere Corporation

      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
      License as published by the Free Software Foundation; either
      version 2.1 of the License, or (at your option) any later version.

      This library is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      Lesser General Public License for more details.

      You should have received a copy of the GNU Lesser General Public
      License along with this library; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

      If you have any questions or comments, please email:

      Dietrich Ayala
      dietrich@...
      http://dietrich.ganx4.com/nusoap

      NuSphere Corporation
      http://www.nusphere.com

      */

      /* load classes

      // necessary classes
      require_once('class.soapclient.php');
      require_once('class.soap_val.php');
      require_once('class.soap_parser.php');
      require_once('class.soap_fault.php');

      // transport classes
      require_once('class.soap_transport_http.php');

      // optional add-on classes
      require_once('class.xmlschema.php');
      require_once('class.wsdl.php');

      // server class
      require_once('class.soap_server.php');*/

      // class variable emulation
      // cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
      $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;

      /**
      *
      * nusoap_base
      *
      * @author Dietrich Ayala <dietrich@...>
      * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
      * @access public
      */
      class nusoap_base {
      /**
      * Identification for HTTP headers.
      *
      * @var string
      * @access private
      */
      var $title = 'NuSOAP';
      /**
      * Version for HTTP headers.
      *
      * @var string
      * @access private
      */
      var $version = '0.7.2';
      /**
      * CVS revision for HTTP headers.
      *
      * @var string
      * @access private
      */
      var $revision = '$Revision: 1.94 $';
      /**
      * Current error string (manipulated by getError/setError)
      *
      * @var string
      * @access private
      */
      var $error_str = '';
      /**
      * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
      *
      * @var string
      * @access private
      */
      var $debug_str = '';
      /**
      * toggles automatic encoding of special characters as entities
      * (should always be true, I think)
      *
      * @var boolean
      * @access private
      */
      var $charencoding = true;
      /**
      * the debug level for this instance
      *
      * @var integer
      * @access private
      */
      var $debugLevel;

      /**
      * set schema version
      *
      * @var string
      * @access public
      */
      var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';

      /**
      * charset encoding for outgoing messages
      *
      * @var string
      * @access public
      */
      var $soap_defencoding = 'ISO-8859-1';
      //var $soap_defencoding = 'UTF-8';

      /**
      * namespaces in an array of prefix => uri
      *
      * this is "seeded" by a set of constants, but it may be altered by code
      *
      * @var array
      * @access public
      */
      var $namespaces = array(
      'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
      'xsd' => 'http://www.w3.org/2001/XMLSchema',
      'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
      'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
      );

      /**
      * namespaces used in the current context, e.g. during serialization
      *
      * @var array
      * @access private
      */
      var $usedNamespaces = array();

      /**
      * XML Schema types in an array of uri => (array of xml type => php type)
      * is this legacy yet?
      * no, this is used by the xmlschema class to verify type => namespace mappings.
      * @var array
      * @access public
      */
      var $typemap = array(
      'http://www.w3.org/2001/XMLSchema' => array(
      'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
      'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
      'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
      // abstract "any" types
      'anyType'=>'string','anySimpleType'=>'string',
      // derived datatypes
      'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
      'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
      'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
      'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
      'http://www.w3.org/2000/10/XMLSchema' => array(
      'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
      'float'=>'double','dateTime'=>'string',
      'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
      'http://www.w3.org/1999/XMLSchema' => array(
      'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
      'float'=>'double','dateTime'=>'string',
      'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
      'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
      'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
      'http://xml.apache.org/xml-soap' => array('Map')
      );

      /**
      * XML entities to convert
      *
      * @var array
      * @access public
      * @deprecated
      * @see expandEntities
      */
      var $xmlEntities = array('quot' => '"','amp' => '&',
      'lt' => '<','gt' => '>','apos' => "'");

      /**
      * constructor
      *
      * @access public
      */
      function nusoap_base() {
      $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
      }

      /**
      * gets the global debug level, which applies to future instances
      *
      * @return integer Debug level 0-9, where 0 turns off
      * @access public
      */
      function getGlobalDebugLevel() {
      return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
      }

      /**
      * sets the global debug level, which applies to future instances
      *
      * @param int $level Debug level 0-9, where 0 turns off
      * @access public
      */
      function setGlobalDebugLevel($level) {
      $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
      }

      /**
      * gets the debug level for this instance
      *
      * @return int Debug level 0-9, where 0 turns off
      * @access public
      */
      function getDebugLevel() {
      return $this->debugLevel;
      }

      /**
      * sets the debug level for this instance
      *
      * @param int $level Debug level 0-9, where 0 turns off
      * @access public
      */
      function setDebugLevel($level) {
      $this->debugLevel = $level;
      }

      /**
      * adds debug data to the instance debug string with formatting
      *
      * @param string $string debug data
      * @access private
      */
      function debug($string){
      if ($this->debugLevel > 0) {
      $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
      }
      }

      /**
      * adds debug data to the instance debug string without formatting
      *
      * @param string $string debug data
      * @access public
      */
      function appendDebug($string){
      if ($this->debugLevel > 0) {
      // it would be nice to use a memory stream here to use
      // memory more efficiently
      $this->debug_str .= $string;
      }
      }

      /**
      * clears the current debug data for this instance
      *
      * @access public
      */
      function clearDebug() {
      // it would be nice to use a memory stream here to use
      // memory more efficiently
      $this->debug_str = '';
      }

      /**
      * gets the current debug data for this instance
      *
      * @return debug data
      * @access public
      */
      function &getDebug() {
      // it would be nice to use a memory stream here to use
      // memory more efficiently
      return $this->debug_str;
      }

      /**
      * gets the current debug data for this instance as an XML comment
      * this may change the contents of the debug data
      *
      * @return debug data as an XML comment
      * @access public
      */
      function &getDebugAsXMLComment() {
      // it would be nice to use a memory stream here to use
      // memory more efficiently
      while (strpos($this->debug_str, '--')) {
      $this->debug_str = str_replace('--', '- -', $this->debug_str);
      }
      return "<!--\n" . $this->debug_str . "\n-->";
      }

      /**
      * expands entities, e.g. changes '<' to '<'.
      *
      * @param string $val The string in which to expand entities.
      * @access private
      */
      function expandEntities($val) {
      if ($this->charencoding) {
      $val = str_replace('&', '&', $val);
      $val = str_replace("'", ''', $val);
      $val = str_replace('"', '"', $val);
      $val = str_replace('<', '<', $val);
      $val = str_replace('>', '>', $val);
      }
      return $val;
      }

      /**
      * returns error string if present
      *
      * @return mixed error string or false
      * @access public
      */
      function getError(){
      if($this->error_str != ''){
      return $this->error_str;
      }
      return false;
      }

      /**
      * sets error string
      *
      * @return boolean $string error string
      * @access private
      */
      function setError($str){
      $this->error_str = $str;
      }

      /**
      * detect if array is a simple array or a struct (associative array)
      *
      * @param mixed $val The PHP array
      * @return string (arraySimple|arrayStruct)
      * @access private
      */
      function isArraySimpleOrStruct($val) {
      $keyList = array_keys($val);
      foreach ($keyList as $keyListValue) {
      if (!is_int($keyListValue)) {
      return 'arrayStruct';
      }
      }
      return 'arraySimple';
      }

      /**
      * serializes PHP values in accordance w/ section 5. Type information is
      * not serialized if $use == 'literal'.
      *
      * @param mixed $val The value to serialize
      * @param string $name The name (local part) of the XML element
      * @param string $type The XML schema type (local part) for the element
      * @param string $name_ns The namespace for the name of the XML element
      * @param string $type_ns The namespace for the type of the element
      * @param array $attributes The attributes to serialize as name=>value pairs
      * @param string $use The WSDL "use" (encoded|literal)
      * @return string The serialized element, possibly with child elements
      * @access public
      */
      function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
      $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
      $this->appendDebug('value=' . $this->varDump($val));
      $this->appendDebug('attributes=' . $this->varDump($attributes));

      if(is_object($val) && get_class($val) == 'soapval'){
      return $val->serialize($use);
      }
      // force valid name if necessary
      if (is_numeric($name)) {
      $name = '__numeric_' . $name;
      } elseif (! $name) {
      $name = 'noname';
      }
      // if name has ns, add ns prefix to name
      $xmlns = '';
      if($name_ns){
      $prefix = 'nu'.rand(1000,9999);
      $name = $prefix.':'.$name;
      $xmlns .= " xmlns:$prefix=\"$name_ns\"";
      }
      // if type is prefixed, create type prefix
      if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
      // need to fix this. shouldn't default to xsd if no ns specified
      // w/o checking against typemap
      $type_prefix = 'xsd';
      } elseif($type_ns){
      $type_prefix = 'ns'.rand(1000,9999);
      $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
      }
      // serialize attributes if present
      $atts = '';
      if($attributes){
      foreach($attributes as $k => $v){
      $atts .= " $k=\"".$this->expandEntities($v).'"';
      }
      }
      // serialize null value
      if (is_null($val)) {
      if ($use == 'literal') {
      // TODO: depends on minOccurs
      return "<$name$xmlns $atts/>";
      } else {
      if (isset($type) && isset($type_prefix)) {
      $type_str = " xsi:type=\"$type_prefix:$type\"";
      } else {
      $type_str = '';
      }
      return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
      }
      }
      // serialize if an xsd built-in primitive type
      if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
      if (is_bool($val)) {
      if ($type == 'boolean') {
      $val = $val ? 'true' : 'false';
      } elseif (! $val) {
      $val = 0;
      }
      } else if (is_string($val)) {
      $val = $this->expandEntities($val);
      }
      if ($use == 'literal') {
      return "<$name$xmlns $atts>$val</$name>";
      } else {
      return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
      }
      }
      // detect type and serialize
      $xml = '';
      switch(true) {
      case (is_bool($val) || $type == 'boolean'):
      if ($type == 'boolean') {
      $val = $val ? 'true' : 'false';
      } elseif (! $val) {
      $val = 0;
      }
      if ($use == 'literal') {
      $xml .= "<$name$xmlns $atts>$val</$name>";
      } else {
      $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
      }
      break;
      case (is_int($val) || is_long($val) || $type == 'int'):
      if ($use == 'literal') {
      $xml .= "<$name$xmlns $atts>$val</$name>";
      } else {
      $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
      }
      break;
      case (is_float($val)|| is_double($val) || $type == 'float'):
      if ($use == 'literal') {
      $xml .= "<$name$xmlns $atts>$val</$name>";
      } else {
      $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
      }
      break;
      case (is_string($val) || $type == 'string'):
      $val = $this->expandEntities($val);
      if ($use == 'literal') {
      $xml .= "<$name$xmlns $atts>$val</$name>";
      } else {
      $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
      }
      break;
      case is_object($val):
      if (! $name) {
      $name = get_class($val);
      $this->debug("In serialize_val, used class name $name as element name");
      } else {
      $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
      }
      foreach(get_object_vars($val) as $k => $v){
      $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
      }
      $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
      break;
      break;
      case (is_array($val) || $type):
      // detect if struct or array
      $valueType = $this->isArraySimpleOrStruct($val);
      if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
      $i = 0;
      if(is_array($val) && count($val)> 0){
      foreach($val as $v){
      if(is_object($v) && get_class($v) == 'soapval'){
      $tt_ns = $v->type_ns;
      $tt = $v->type;
      } elseif (is_array($v)) {
      $tt = $this->isArraySimpleOrStruct($v);
      } else {
      $tt = gettype($v);
      }
      $array_types[$tt] = 1;
      // TODO: for literal, the name should be $name
      $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
      ++$i;
      }
      if(count($array_types) > 1){
      $array_typename = 'xsd:anyType';
      } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
      if ($tt == 'integer') {
      $tt = 'int';
      }
      $array_typename = 'xsd:'.$tt;
      } elseif(isset($tt) && $tt == 'arraySimple'){
      $array_typename = 'SOAP-ENC:Array';
      } elseif(isset($tt) && $tt == 'arrayStruct'){
      $array_typename = 'unnamed_struct_use_soapval';
      } else {
      // if type is prefixed, create type prefix
      if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
      $array_typename = 'xsd:' . $tt;
      } elseif ($tt_ns) {
      $tt_prefix = 'ns' . rand(1000, 9999);
      $array_typename = "$tt_prefix:$tt";
      $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
      } else {
      $array_typename = $tt;
      }
      }
      $array_type = $i;
      if ($use == 'literal') {
      $type_str = '';
      } else if (isset($type) && isset($type_prefix)) {
      $type_str = " xsi:type=\"$type_prefix:$type\"";
      } else {
      $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
      }
      // empty array
      } else {
      if ($use == 'literal') {
      $type_str = '';
      } else if (isset($type) && isset($type_prefix)) {
      $type_str = " xsi:type=\"$type_prefix:$type\"";
      } else {
      $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
      }
      }
      // TODO: for array in literal, there is no wrapper here
      $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
      } else {
      // got a struct
      if(isset($type) && isset($type_prefix)){
      $type_str = " xsi:type=\"$type_prefix:$type\"";
      } else {
      $type_str = '';
      }
      if ($use == 'literal') {
      $xml .= "<$name$xmlns $atts>";
      } else {
      $xml .= "<$name$xmlns$type_str$atts>";
      }
      foreach($val as $k => $v){
      // Apache Map
      if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
      $xml .= '<item>';
      $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
      $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
      $xml .= '</item>';
      } else {
      $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
      }
      }
      $xml .= "</$name>";
      }
      break;
      default:
      $xml .= 'not detected, got '.gettype($val).' for '.$val;
      break;
      }
      return $xml;
      }

      /**
      * serializes a message
      *
      * @param string $body the XML of the SOAP body
      * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
      * @param array $namespaces optional the namespaces used in generating the body and headers
      * @param string $style optional (rpc|document)
      * @param string $use optional (encoded|literal)
      * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
      * @return string the message
      * @access public
      */
      function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
      // TODO: add an option to automatically run utf8_encode on $body and $headers
      // if $this->soap_defencoding is UTF-8. Not doing this automatically allows
      // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1

      $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
      $this->debug("headers:");
      $this->appendDebug($this->varDump($headers));
      $this->debug("namespaces:");
      $this->appendDebug($this->varDump($namespaces));

      // serialize namespaces
      $ns_string = '';
      foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
      $ns_string .= " xmlns:$k=\"$v\"";
      }
      if($encodingStyle) {
      $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
      }

      // serialize headers
      if($headers){
      if (is_array($headers)) {
      $xml = '';
      foreach ($headers as $header) {
      $xml .= $this->serialize_val($header, false, false, false, false, false, $use);
      }
      $headers = $xml;
      $this->debug("In serializeEnvelope, serialzied array of headers to $headers");
      }
      $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
      }
      // serialize envelope
      return
      '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
      '<SOAP-ENV:Envelope'.$ns_string.">".
      $headers.
      "<SOAP-ENV:Body>".
      $body.
      "</SOAP-ENV:Body>".
      "</SOAP-ENV:Envelope>";
      }

      /**
      * formats a string to be inserted into an HTML stream
      *
      * @param string $str The string to format
      * @return string The formatted string
      * @access public
      * @deprecated
      */
      function formatDump($str){
      $str = htmlspecialchars($str);
      return nl2br($str);
      }

      /**
      * contracts (changes namespace to prefix) a qualified name
      *
      * @param string $qname qname
      * @return string contracted qname
      * @access private
      */
      function contractQname($qname){
      // get element namespace
      //$this->xdebug("Contract $qname");
      if (strrpos($qname, ':')) {
      // get unqualified name
      $name = substr($qname, strrpos($qname, ':') + 1);
      // get ns
      $ns = substr($qname, 0, strrpos($qname, ':'));
      $p = $this->getPrefixFromNamespace($ns);
      if ($p) {
      return $p . ':' . $name;
      }
      return $qname;
      } else {
      return $qname;
      }
      }

      /**
      * expands (changes prefix to namespace) a qualified name
      *
      * @param string $string qname
      * @return string expanded qname
      * @access private
      */
      function expandQname($qname){
      // get element prefix
      if(strpos($qname,':') && !ereg('^http://',$qname)){
      // get unqualified name
      $name = substr(strstr($qname,':'),1);
      // get ns prefix
      $prefix = substr($qname,0,strpos($qname,':'));
      if(isset($this->namespaces[$prefix])){
      return $this->namespaces[$prefix].':'.$name;
      } else {
      return $qname;
      }
      } else {
      return $qname;
      }
      }

      /**
      * returns the local part of a prefixed string
      * returns the original string, if not prefixed
      *
      * @param string $str The prefixed string
      * @return string The local part
      * @access public
      */
      function getLocalPart($str){
      if($sstr = strrchr($str,':')){
      // get unqualified name
      return substr( $sstr, 1 );
      } else {
      return $str;
      }
      }

      /**
      * returns the prefix part of a prefixed string
      * returns false, if not prefixed
      *
      * @param string $str The prefixed string
      * @return mixed The prefix or false if there is no prefix
      * @access public
      */
      function getPrefix($str){
      if($pos = strrpos($str,':')){
      // get prefix
      return substr($str,0,$pos);
      }
      return false;
      }

      /**
      * pass it a prefix, it returns a namespace
      *
      * @param string $prefix The prefix
      * @return mixed The namespace, false if no namespace has the specified prefix
      * @access public
      */
      function getNamespaceFromPrefix($prefix){
      if (isset($this->namespaces[$prefix])) {
      return $this->namespaces[$prefix];
      }
      //$this->setError("No namespace registered for prefix '$prefix'");
      return false;
      }

      /**
      * returns the prefix for a given namespace (or prefix)
      * or false if no prefixes registered for the given namespace
      *
      * @param string $ns The namespace
      * @return mixed The prefix, false if the namespace has no prefixes
      * @access public
      */
      function getPrefixFromNamespace($ns) {
      foreach ($this->namespaces as $p => $n) {
      if ($ns == $n || $ns == $p) {
      $this->usedNamespaces[$p] = $n;
      return $p;
      }
      }
      return false;
      }

      /**
      * returns the time in ODBC canonical form with microseconds
      *
      * @return string The time in ODBC canonical form with microseconds
      * @access public
      */
      function getmicrotime() {
      if (function_exists('gettimeofday')) {
      $tod = gettimeofday();
      $sec = $tod['sec'];
      $usec = $tod['usec'];
      } else {
      $sec = time();
      $usec = 0;
      }
      return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
      }

      /**
      * Returns a string with the output of var_dump
      *
      * @param mixed $data The variable to var_dump
      * @return string The output of var_dump
      * @access public
      */
      function varDump($data) {
      ob_start();
      var_dump($data);
      $ret_val = ob_get_contents();
      ob_end_clean();
      return $ret_val;
      }
      }

      // XML Schema Datatype Helper Functions

      //xsd:dateTime helpers

      /**
      * convert unix timestamp to ISO 8601 compliant date string
      *
      * @param string $timestamp Unix time stamp
      * @access public
      */
      function timestamp_to_iso8601($timestamp,$utc=true){
      $datestr = date('Y-m-d\TH:i:sO',$timestamp);
      if($utc){
      $eregStr =
      '([0-9]{4})-'. // centuries & years CCYY-
      '([0-9]{2})-'. // months MM-
      '([0-9]{2})'. // days DD
      'T'. // separator T
      '([0-9]{2}):'. // hours hh:
      '([0-9]{2}):'. // minutes mm:
      '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
      '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's

      if(ereg($eregStr,$datestr,$regs)){
      return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
      }
      return false;
      } else {
      return $datestr;
      }
      }

      /**
      * convert ISO 8601 compliant date string to unix timestamp
      *
      * @param string $datestr ISO 8601 compliant date string
      * @access public
      */
      function iso8601_to_timestamp($datestr){
      $eregStr =
      '([0-9]{4})-'. // centuries & years CCYY-
      '([0-9]{2})-'. // months MM-
      '([0-9]{2})'. // days DD
      'T'. // separator T
      '([0-9]{2}):'. // hours hh:
      '([0-9]{2}):'. // minutes mm:
      '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
      '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
      if(ereg($eregStr,$datestr,$regs)){
      // not utc
      if($regs[8] != 'Z'){
      $op = substr($regs[8],0,1);
      $h = substr($regs[8],1,2);
      $m = substr($regs[8],strlen($regs[8])-2,2);
      if($op == '-'){
      $regs[4] = $regs[4] + $h;
      $regs[5] = $regs[5] + $m;
      } elseif($op == '+'){
      $regs[4] = $regs[4] - $h;
      $regs[5] = $regs[5] - $m;
      }
      }
      return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
      } else {
      return false;
      }
      }

      /**
      * sleeps some number of microseconds
      *
      * @param string $usec the number of microseconds to sleep
      * @access public
      * @deprecated
      */
      function usleepWindows($usec)
      {
      $start = gettimeofday();

      do
      {
      $stop = gettimeofday();
      $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
      + $stop['usec'] - $start['usec'];
      }
      while ($timePassed < $usec);
      }

      ?><?php



      /**
      * Contains information for a SOAP fault.
      * Mainly used for returning faults from deployed functions
      * in a server instance.
      * @author Dietrich Ayala <dietrich@...>
      * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
      * @access public
      */
      class soap_fault extends nusoap_base {
      /**
      * The fault code (client|server)
      * @var string
      * @access private
      */
      var $faultcode;
      /**
      * The fault actor
      * @var string
      * @access private
      */
      var $faultactor;
      /**
      * The fault string, a description of the fault
      * @var string
      * @access private
      */
      var $faultstring;
      /**
      * The fault detail, typically a string or array of string
      * @var mixed
      * @access private
      */
      var $faultdetail;

      /**
      * constructor
      *
      * @param string $faultcode (client | server)
      * @param string $faultactor only used when msg routed between multiple actors
      * @param string $faultstring human readable error message
      * @param mixed $faultdetail detail, typically a string or array of string
      */
      function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
      parent::nusoap_base();
      $this->faultcode = $faultcode;
      $this->faultactor = $faultactor;
      $this->faultstring = $faultstring;
      $this->faultdetail = $faultdetail;
      }

      /**
      * serialize a fault
      *
      * @return string The serialization of the fault instance.
      * @access public
      */
      function serialize(){
      $ns_string = '';
      foreach($this->namespaces as $k => $v){
      $ns_string .= "\n xmlns:$k=\"$v\"";
      }
      $return_msg =
      '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
      '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
      '<SOAP-ENV:Body>'.
      '<SOAP-ENV:Fault>'.
      $this->serialize_val($this->faultcode, 'faultcode').
      $this->serialize_val($this->faultactor, 'faultactor').
      $this->serialize_val($this->faultstring, 'faultstring').
      $this->serialize_val($this->faultdetail, 'detail').
      '</SOAP-ENV:Fault>'.
      '</SOAP-ENV:Body>'.
      '</SOAP-ENV:Envelope>';
      return $return_msg;
      }
      }



      ?><?php



      /**
      * parses an XML Schema, allows access to it's data, other utility methods
      * no validation... yet.
      * very experimental and limited. As is discussed on XML-DEV, I'm one of the people
      * that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
      * tutorials I refer to :)
      *
      * @author Dietrich Ayala <dietrich@...>
      * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
      * @access public
      */
      class XMLSchema extends nusoap_base {

      // files
      var $schema = '';
      var $xml = '';
      // namespaces
      var $enclosingNamespaces;
      // schema info
      var $schemaInfo = array();
      var $schemaTargetNamespace = '';
      // types, elements, attributes defined by the schema
      var $attributes = array();
      var $complexTypes = array();
      var $complexTypeStack = array();
      var $currentComplexType = null;
      var $elements = array();
      var $elementStack = array();
      var $currentElement = null;
      var $simpleTypes = array();
      var $simpleTypeStack = array();
      var $currentSimpleType = null;
      // imports
      var $imports = array();
      // parser vars
      var $parser;
      var $position = 0;
      var $depth = 0;
      var $depth_array = array();
      var $message = array();
      var $defaultNamespace = array();

      /**
      * constructor
      *
      * @param string $schema schema document URI
      * @param string $xml xml document URI
      * @param string $namespaces namespaces defined in enclosing XML
      * @access public
      */
      function XMLSchema($schema='',$xml='',$namespaces=array()){
      parent::nusoap_base();
      $this->debug('xmlschema class instantiated, inside constructor');
      // files
      $this->schema = $schema;
      $this->xml = $xml;

      // namespaces
      $this->enclosingNamespaces = $namespaces;
      $this->namespaces = array_merge($this->namespaces, $namespaces);

      // parse schema file
      if($schema != ''){
      $this->debug('initial schema file: '.$schema);
      $this->parseFile($schema, 'schema');
      }

      // parse xml file
      if($xml != ''){
      $this->debug('initial xml file: '.$xml);
      $this->parseFile($xml, 'xml');
      }

      }

      /**
      * parse an XML file
      *
      * @param string $xml, path/URL to XML file
      * @param string $type, (schema | xml)
      * @return boolean
      * @access public
      */
      function parseFile($xml,$type){
      // parse xml file
      if($xml != ""){
      $xmlStr = @join("",@file($xml));
      if($xmlStr == ""){
      $msg = 'Error reading XML from '.$xml;
      $this->setError($msg);
      $this->debug($msg);
      return false;
      } else {
      $this->debug("parsing $xml");
      $this->parseString($xmlStr,$type);
      $this->debug("done parsing $xml");
      return true;
      }
      }
      return false;
      }

      /**
      * parse an XML string
      *
      * @param string $xml path or URL
      * @param string $type, (schema|xml)
      * @access private
      */
      function parseString($xml,$type){
      // parse xml string
      if($xml != ""){

      // Create an XML parser.
      $this->parser = xml_parser_create();
      // Set the options for parsing the XML data.
      xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);

      // Set the object for the parser.
      xml_set_object($this->parser, $this);

      // Set the element handlers for the parser.
      if($type == "schema"){
      xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
      xml_set_character_data_handler($this->parser,'schemaCharacterData');
      } elseif($type == "xml"){
      xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
      xml_set_character_data_handler($this->parser,'xmlCharacterData');
      }

      // Parse the XML file.
      if(!xml_parse($this->parser,$xml,true)){
      // Display an error message.
      $errstr = sprintf('XML error parsing XML schema on line %d: %s',
      xml_get_current_line_number($this->parser),
      xml_error_string(xml_get_error_code($this->parser))
      );
      $this->debug($errstr);
      $this->debug("XML payload:\n" . $xml);
      $this->setError($errstr);
      }

      xml_parser_free($this->parser);
      } else{
      $this->debug('no xml passed to parseString()!!');
      $this->setError('no xml passed to parseString()!!');
      }
      }

      /**
      * start-element handler
      *
      * @param string $parser XML parser object
      * @param string $name element name
      * @param string $attrs associative array of attributes
      * @access private
      */
      function schemaStartElement($parser, $name, $attrs) {

      // position in the total number of elements, starting from 0
      $pos = $this->position++;
      $depth = $this->depth++;
      // set self as current value for this depth
      $this->depth_array[$depth] = $pos;
      $this->message[$pos] = array('cdata' => '');
      if ($depth > 0) {
      $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
      } else {
      $this->defaultNamespace[$pos] = false;
      }

      // get element prefix
      if($prefix = $this->getPrefix($name)){
      // get unqualified name
      $name = $this->getLocalPart($name);
      } else {
      $prefix = '';
      }

      // loop thru attributes, expanding, and registering namespace declarations
      if(count($attrs) > 0){
      foreach($attrs as $k => $v){
      // if ns declarations, add to class level array of valid namespaces
      if(ereg("^xmlns",$k)){
      //$this->xdebug("$k: $v");
      //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
      if($ns_prefix = substr(strrchr($k,':'),1)){
      //$this->xdebug("Add namespace[$ns_prefix] = $v");
      $this->namespaces[$ns_prefix] = $v;
      } else {
      $this->defaultNamespace[$pos] = $v;
      if (! $this->getPrefixFromNamespace($v)) {
      $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
      }
      }
      if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
      $this->XMLSchemaVersion = $v;
      $this->namespaces['xsi'] = $v.'-instance';
      }
      }
      }
      foreach($attrs as $k => $v){
      // expand each attribute
      $k = strpos($k,':') ? $this->expandQname($k) : $k;
      $v = strpos($v,':') ? $this->expandQname($v) : $v;
      $eAttrs[$k] = $v;
      }
      $attrs = $eAttrs;
      } else {
      $attrs = array();
      }
      // find status, register data
      switch($name){
      case 'all': // (optional) compositor content for a complexType
      case 'choice':
      case 'group':
      case 'sequence':
      //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
      $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
      //if($name == 'all' || $name == 'sequence'){
      // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
      //}
      break;
      case 'attribute': // complexType attribute
      //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
      $this->xdebug("parsing attribute:");
      $this->appendDebug($this->varDump($attrs));
      if (!isset($attrs['form'])) {
      $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
      }
      if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
      $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
      if (!strpos($v, ':')) {
      // no namespace in arrayType attribute value...
      if ($this->defaultNamespace[$pos]) {
      // ...so use the default
      $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
      }
      }
      }
      if(isset($attrs['name'])){
      $this->attributes[$attrs['name']] = $attrs;
      $aname = $attrs['name'];
      } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
      if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
      $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
      } else {
      $aname = '';
      }
      } elseif(isset($attrs['ref'])){
      $aname = $attrs['ref'];
      $this->attributes[$attrs['ref']] = $attrs;
      }

      if($this->currentComplexType){ // This should *always* be
      $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
      }
      // arrayType attribute
      if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
      $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
      $prefix = $this->getPrefix($aname);
      if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
      $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
      } else {
      $v = '';
      }
      if(strpos($v,'[,]')){
      $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
      }
      $v = substr($v,0,strpos($v,'[')); // clip the []
      if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
      $v = $this->XMLSchemaVersion.':'.$v;
      }
      $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
      }
      break;
      case 'complexContent': // (optional) content for a complexType
      break;
      case 'complexType':
      array_push($this->complexTypeStack, $this->currentComplexType);
      if(isset($attrs['name'])){
      $this->xdebug('processing named complexType '.$attrs['name']);
      //$this->currentElement = false;
      $this->currentComplexType = $attrs['name'];
      $this->complexTypes[$this->currentComplexType] = $attrs;
      $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
      // This is for constructs like
      // <complexType name="ListOfString" base="soap:Array">
      // <sequence>
      // <element name="string" type="xsd:string"
      // minOccurs="0" maxOccurs="unbounded" />
      // </sequence>
      // </complexType>
      if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
      $this->xdebug('complexType is unusual array');
      $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
      } else {
      $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
      }
      }else{
      $this->xdebug('processing unnamed complexType for element '.$this->currentElement);
      $this->currentComplexType = $this->currentElement . '_ContainedType';
      //$this->currentElement = false;
      $this->complexTypes[$this->currentComplexType] = $attrs;
      $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
      // This is for constructs like
      // <complexType name="ListOfString" base="soap:Array">
      // <sequence>
      // <element name="string" type="xsd:string"
      // minOccurs="0" maxOccurs="unbounded" />
      // </sequence>
      // </complexType>
      if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
      $this->xdebug('complexType is unusual array');
      $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
      } else {
      $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
      }
      }
      break;
      case 'element':
      array_push($this->elementStack, $this->currentElement);
      // elements defined as part of a complex type should
      // not really be added to $this->elements, but for some
      // reason, they are
      if (!isset($attrs['form'])) {
      $attrs['form'] = $this->schemaInfo['elementFormDefault'];
      }
      if(isset($attrs['type'])){
      $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
      if (! $this->getPrefix($attrs['type'])) {
      if ($this->defaultNamespace[$pos]) {
      $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
      $this->xdebug('used default namespace to make type ' . $attrs['type']);
      }
      }
      // This is for constructs like
      // <complexType name="ListOfString" base="soap:Array">
      // <sequence>
      // <element name="string" type="xsd:string"
      // minOccurs="0" maxOccurs="unbounded" />
      // </sequence>
      // </complexType>
      if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
      $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
      $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
      }
      $this->currentElement = $attrs['name'];
      $this->elements[ $attrs['name'] ] = $attrs;
      $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
      $ename = $attrs['name'];
      } elseif(isset($attrs['ref'])){
      $this->xdebug("processing element as ref to ".$attrs['ref']);
      $this->currentElement = "ref to ".$attrs['ref'];
      $ename = $this->getLocalPart($attrs['ref']);
      } else {
      $this->xdebug("processing untyped element ".$attrs['name']);
      $this->currentElement = $attrs['name'];
      $this->elements[ $attrs['name'] ] = $attrs;
      $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
      $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
      $this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
      $ename = $attrs['name'];
      }
      if(isset($ename) && $this->currentComplexType){
      $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
      }
      break;
      case 'enumeration': // restriction value list member
      $this->xdebug('enumeration ' . $attrs['value']);
      if ($this->currentSimpleType) {
      $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
      } elseif ($this->currentComplexType) {
      $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
      }
      break;
      case 'extension': // simpleContent or complexContent type extension
      $this->xdebug('extension ' . $attrs['base']);
      if ($this->currentComplexType) {
      $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
      }
      break;
      case 'import':
      if (isset($attrs['schemaLocation'])) {
      //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
      $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
      } else {
      //$this->xdebug('import namespace ' . $attrs['namespace']);
      $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
      if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
      $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
      }
      }
      break;
      case 'list': // simpleType value list
      break;
      case 'restriction': // simpleType, simpleContent or complexContent value restriction
      $this->xdebug('restriction ' . $attrs['base']);
      if($this->currentSimpleType){
      $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
      } elseif($this->currentComplexType){
      $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
      if(strstr($attrs['base'],':') == ':Array'){
      $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
      }
      }
      break;
      case 'schema':
      $this->schemaInfo = $attrs;
      $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
      if (isset($attrs['targetNamespace'])) {
      $this->schemaTargetNamespace = $attrs['targetNamespace'];
      }
      if (!isset($attrs['elementFormDefault'])) {
      $this->schemaInfo['elementFormDefault'] = 'unqualified';
      }
      if (!isset($attrs['attributeFormDefault'])) {
      $this->schemaInfo['attributeFormDefault'] = 'unqualified';
      }
      break;
      case 'simpleContent': // (optional) content for a complexType
      break;
      case 'simpleType':
      array_push($this->simpleTypeStack, $this->currentSimpleType);
      if(isset($attrs['name'])){
      $this->xdebug("processing simpleType for name " . $attrs['name']);
      $this->currentSimpleType = $attrs['name'];
      $this->simpleTypes[ $attrs['name'] ] = $attrs;
      $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
      $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
      } else {
      $this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
      $this->currentSimpleType = $this->currentElement . '_ContainedType';
      //$this->currentElement = false;
      $this->simpleTypes[$this->currentSimpleType] = $attrs;
      $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
      }
      break;
      case 'union': // simpleType type list
      break;
      default:
      //$this->xdebug("do not have anything to do for element $name");
      }
      }

      /**
      * end-element handler
      *
      * @param string $parser XML parser object
      * @param string $name element name
      * @access private
      */
      function schemaEndElement($parser, $name) {
      // bring depth down a notch
      $this->depth--;
      // position of current element is equal to the last value left in depth_array for my depth
      if(isset($this->depth_array[$this->depth])){
      $pos = $this->depth_array[$this->depth];
      }
      // get element prefix
      if ($prefix = $this->getPrefix($name)){
      // get unqualified name
      $name = $this->getLocalPart($name);
      } else {
      $prefix = '';
      }
      // move on...
      if($name == 'complexType'){
      $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
      $this->currentComplexType = array_pop($this->complexTypeStack);
      //$this->currentElement = false;
      }
      if($name == 'element'){
      $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
      $this->currentElement = array_pop($this->elementStack);
      }
      if($name == 'simpleType'){
      $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
      $this->currentSimpleType = array_pop($this->simpleTypeStack);
      }
      }

      /**
      * element content handler
      *
      * @param string $parser XML parser object
      * @param string $data element content
      * @access private
      */
      function schemaCharacterData($parser, $data){
      $pos = $this->depth_array[$this->depth - 1];
      $this->message[$pos]['cdata'] .= $data;
      }

      /**
      * serialize the schema
      *
      * @access public
      */
      function serializeSchema(){

      $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
      $xml = '';
      // imports
      if (sizeof($this->imports) > 0) {
      foreach($this->imports as $ns => $list) {
      foreach ($list as $ii) {
      if ($ii['location'] != '') {
      $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
      } else {
      $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
      }
      }
      }
      }
      // complex types
      foreach($this->complexTypes as $typeName => $attrs){
      $contentStr = '';
      // serialize child elements
      if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
      foreach($attrs['elements'] as $element => $eParts){
      if(isset($eParts['ref'])){
      $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
      } else {
      $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
      foreach ($eParts as $aName => $aValue) {
      // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
      if ($aName != 'name' && $aName != 'type') {
      $contentStr .= " $aName=\"$aValue\"";
      }
      }
      $contentStr .= "/>\n";
      }
      }
      // compositor wraps elements
      if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
      $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
      }
      }
      // attributes
      if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
      foreach($attrs['attrs'] as $attr => $aParts){
      $contentStr .= " <$schemaPrefix:attribute";
      foreach ($aParts as $a => $v) {
      if ($a == 'ref' || $a == 'type') {
      $contentStr .= " $a=\"".$this->contractQName($v).'"';
      } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
      $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
      $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
      } else {
      $contentStr .= " $a=\"$v\"";
      }
      }
      $contentStr .= "/>\n";
      }
      }
      // if restriction
      if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
      $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
      // complex or simple content
      if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
      $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
      }
      }
      // finalize complex type
      if($contentStr != ''){
      $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
      } else {
      $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
      }
      $xml .= $contentStr;
      }
      // simple types
      if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
      foreach($this->simpleTypes as $typeName => $eParts){
      $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
      if (isset($eParts['enumeration'])) {
      foreach ($eParts['enumeration'] as $e) {
      $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
      }
      }
      $xml .= " </$schemaPrefix:simpleType>";
      }
      }
      // elements
      if(isset($this->elements) && count($this->elements) > 0){
      foreach($this->elements as $element => $eParts){
      $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
      }
      }
      // attributes
      if(isset($this->attributes) && count($this->attributes) > 0){
      foreach($this->attributes as $attr => $aParts){
      $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
      }
      }
      // finish 'er up
      $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
      foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
      $el .= " xmlns:$nsp=\"$ns\"\n";
      }
      $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
      return $xml;
      }

      /**
      * adds debug data to the clas level debug string
      *
      * @param string $string debug data
      * @access private
      */
      function xdebug($string){
      $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
      }

      /**
      * get the PHP type of a user defined type in the schema
      * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
      * returns false if no type exists, or not w/ the given namespace
      * else returns a string that is either a native php type, or 'struct'
      *
      * @param string $type, name of defined type
      * @param string $ns, namespace of type
      * @return mixed
      * @access public
      * @deprecated
      */
      function getPHPType($type,$ns){
      if(isset($this->typemap[$ns][$type])){
      //print "found type '$type' and ns $ns in typemap<br>";
      return $this->typemap[$ns][$type];
      } elseif(isset($this->complexTypes[$type])){
      //print "getting type '$type' and ns $ns from complexTypes array<br>";
      return $this->complexTypes[$type]['phpType'];
      }
      return false;
      }

      /**
      * returns an associative array of information about a given type
      * returns false if no type exists by the given name
      *
      * For a complexType typeDef = array(
      * 'restrictionBase' => '',
      * 'phpType' => '',
      * 'compositor' => '(sequence|all)',
      * 'elements' => array(), // refs to elements array
      * 'attrs' => array() // refs to attributes array
      * ... and so on (see addComplexType)
      * )
      *
      * For simpleType or element, the array has different keys.
      *
      * @param string
      * @return mixed
      * @access public
      * @see addComplexType
      * @see addSimpleType
      * @see addElement
      */
      function getTypeDef($type){
      //$this->debug("in getTypeDef for type $type");
      if(isset($this->complexTypes[$type])){
      $this->xdebug("in getTypeDef, found complexType $type");
      return $this->complexTypes[$type];
      } elseif(isset($this->simpleTypes[$type])){
      $this->xdebug("in getTypeDef, found simpleType $type");
      if (!isset($this->simpleTypes[$type]['phpType'])) {
      // get info for type to tack onto the simple type
      // TODO: can this ever really apply (i.e. what is a simpleType really?)
      $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
      $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
      $etype = $this->getTypeDef($uqType);
      if ($etype) {
      $this->xdebug("in getTypeDef, found type for simpleType $type:");
      $this->xdebug($this->varDump($etype));
      if (isset($etype['phpType'])) {
      $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
      }
      if (isset($etype['elements'])) {
      $this->simpleTypes[$type]['elements'] = $etype['elements'];
      }
      }
      }
      return $this->simpleTypes[$type];
      } elseif(isset($this->elements[$type])){
      $this->xdebug("in getTypeDef, found element $type");
      if (!isset($this->elements[$type]['phpType'])) {
      // get info for type to tack onto the element
      $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
      $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
      $etype = $this->getTypeDef($uqType);
      if ($etype) {
      $this->xdebug("in getTypeDef, found type for element $type:");
      $this->xdebug($this->varDump($etype));
      if (isset($etype['phpType'])) {
      $this->elements[$type]['phpType'] = $etype['phpType'];
      }
      if (isset($etype['elements'])) {
      $this->elements[$type]['elements'] = $etype['elements'];
      }
      } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
      $this->xdebug("in getTypeDef, element $type is an XSD type");
      $this->elements[$type]['phpType'] = 'scalar';
      }
      }
      return $this->elements[$type];
      } elseif(isset($this->attributes[$type])){
      $this->xdebug("in getTypeDef, found attribute $type");
      return $this->attributes[$type];
      } elseif (ereg('_ContainedType$', $type)) {
      $this->xdebug("in getTypeDef, have an untyped element $type");
      $typeDef['typeClass'] = 'simpleType';
      $typeDef['phpType'] = 'scalar';
      $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
      return $typeDef;
      }
      $this->xdebug("in getTypeDef, did not find $type");
      return false;
      }

      /**
      * returns a sample serialization of a given type, or false if no type by the given name
      *
      * @param string $type, name of type
      * @return mixed
      * @access public
      * @deprecated
      */
      function serializeTypeDef($type){
      //print "in sTD() for type $type<br>";
      if($typeDef = $this->getTypeDef($type)){
      $str .= '<'.$type;
      if(is_array($typeDef['attrs'])){
      foreach($attrs as $attName => $data){
      $str .= " $attName=\"{type = ".$data['type']."}\"";
      }
      }
      $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
      if(count($typeDef['elements']) > 0){
      $str .= ">";
      foreach($typeDef['elements'] as $element => $eData){
      $str .= $this->serializeTypeDef($element);
      }
      $str .= "</$type>";
      } elseif($typeDef['typeClass'] == 'element') {
      $str .= "></$type>";
      } else {
      $str .= "/>";
      }
      return $str;
      }
      return false;
      }

      /**
      * returns HTML form elements that allow a user
      * to enter values for creating an instance of the given type.
      *
      * @param string $name, name for type instance
      * @param string $type, name of type
      * @return string
      * @access public
      * @deprecated
      */
      function typeToForm($name,$type){
      // get typedef
      if($typeDef = $this->getTypeDef($type)){
      // if struct
      if($typeDef['phpType'] == 'struct'){
      $buffer .= '<table>';
      foreach($typeDef['elements'] as $child => $childDef){
      $buffer .= "
      <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
      <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
      }
      $buffer .= '</table>';
      // if array
      } elseif($typeDef['phpType'] == 'array'){
      $buffer .= '<table>';
      for($i=0;$i < 3; $i++){
      $buffer .= "
      <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
      <td><input type='text' name='parameters[".$name."][]'></td></tr>";
      }
      $buffer .= '</table>';
      // if scalar
      } else {
      $buffer .= "<input type='text' name='parameters[$name]'>";
      }
      } else {
      $buffer .= "<input type='text' name='parameters[$name]'>";
      }
      return $buffer;
      }

      /**
      * adds a complex type to the schema
      *
      * example: array
      *
      * addType(
      * 'ArrayOfstring',
      * 'complexType',
      * 'array',
      * '',
      * 'SOAP-ENC:Array',
      * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
      * 'xsd:string'
      * );
      *
      * example: PHP associative array ( SOAP Struct )
      *
      * addType(
      * 'SOAPStruct',
      * 'complexType',
      * 'struct',
      * 'all',
      * array('myVar'=> array('name'=>'myVar','type'=>'string')
      * );
      *
      * @param name
      * @param typeClass (complexType|simpleType|attribute)
      * @param phpType: currently supported are array and struct (php assoc array)
      * @param compositor (all|sequence|choice)
      * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
      * @param elements = array ( name = array(name=>'',type=>'') )
      * @param attrs = array(
      * array(
      * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
      * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
      * )
      * )
      * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
      * @access public
      * @see getTypeDef
      */
      function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
      $this->complexTypes[$name] = array(
      'name' => $name,
      'typeClass' => $typeClass,
      'phpType' => $phpType,
      'compositor'=> $compositor,
      'restrictionBase' => $restrictionBase,
      'elements' => $elements,
      'attrs' => $attrs,
      'arrayType' => $arrayType
      );

      $this->xdebug("addComplexType $name:");
      $this->appendDebug($this->varDump($this->complexTypes[$name]));
      }

      /**
      * adds a simple type to the schema
      *
      * @param string $name
      * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
      * @param string $typeClass (should always be simpleType)
      * @param string $phpType (should always be scalar)
      * @param array $enumeration array of values
      * @access public
      * @see xmlschema
      * @see getTypeDef
      */
      function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
      $this->simpleTypes[$name] = array(
      'name' => $name,
      'typeClass' => $typeClass,
      'phpType' => $phpType,
      'type' => $restrictionBase,
      'enumeration' => $enumeration
      );

      $this->xdebug("addSimpleType $name:");
      $this->appendDebug($this->varDump($this->simpleTypes[$name]));
      }

      /**
      * adds an element to the schema
      *
      * @param array $attrs attributes that must include name and type
      * @see xmlschema
      * @access public
      */
      function addElement($attrs) {
      if (! $this->getPrefix($attrs['type'])) {
      $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
      }
      $this->elements[ $attrs['name'] ] = $attrs;
      $this->elements[ $attrs['name'] ]['typeClass'] = 'element';

      $this->xdebug("addElement " . $attrs['name']);
      $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
      }
      }



      ?><?php



      /**
      * For creating serializable abstractions of native PHP types. This class
      * allows element name/namespace, XSD type, and XML attributes to be
      * associated with a value. This is extremely useful when WSDL is not
      * used, but is also useful when WSDL is used with polymorphic types, including
      * xsd:anyType and user-defined types.
      *
      * @author Dietrich Ayala <dietrich@...>
      * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
      * @access public
      */
      class soapval extends nusoap_base {
      /**
      * The XML element name
      *
      * @var string
      * @access private
      */
      var $name;
      /**
      * The XML type name (string or false)
      *
      * @var mixed
      * @access private
      */
      var $type;
      /**
      * The PHP value
      *
      * @var mixed
      * @access private
      */
      var $value;
      /**
      * The XML element namespace (string or false)
      *
      * @var mixed
      * @access private
      */
      var $element_ns;
      /**
      * The XML type namespace (string or false)
      *
      * @var mixed
      * @access private
      */
      var $type_ns;
      /**
      * The XML element attributes (array or false)
      *
      * @var mixed
      * @access private
      */
      var $attributes;

      /**
      * constructor
      *
      * @param string $name optional name
      * @param mixed $type optional type name
      * @param mixed $value optional value
      * @param mixed $element_ns optional namespace of value
      * @param mixed $type_ns optional namespace of type
      * @param mixed $attributes associative array of attributes to add to element serialization
      * @access public
      */
      function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
      parent::nusoap_base();
      $this->name = $name;
      $this->type = $type;
      $this->value = $value;
      $this->element_ns = $element_ns;
      $this->type_ns = $type_ns;
      $this->attributes = $attributes;
      }

      /**
      * return serialized value
      *
      * @param string $use The WSDL use value (encoded|literal)
      * @return string XML data
      <br/><br/>(Message over 64 KB, truncated)
    • Atkinson, Robert
      One of many sites that cover this topic :- http://www.onlamp.com/pub/a/php/2007/07/26/php-web-services.html ... From: php-objects@yahoogroups.com
      Message 2 of 7 , Feb 7, 2008
      • 0 Attachment
        One of many sites that cover this topic :-

        http://www.onlamp.com/pub/a/php/2007/07/26/php-web-services.html

        -----Original Message-----
        From: php-objects@yahoogroups.com [mailto:php-objects@yahoogroups.com] On
        Behalf Of binoy
        Sent: 05 February 2008 06:40
        To: php-objects@yahoogroups.com
        Subject: [php-objects] web service

        Hi Every one,
        I want to write a web service.
        server is php and cleint is .net.

        my requirement is that i want to return product list (all the product or
        single product -- that depend on the id we are getting from client machine )
        from an oscommerce site.the client is .net and the server is php.

        Actually i dont know anything abt the webservices. Can anybody help me.


        ***********************************************************************************
        Any opinions expressed in email are those of the individual and not necessarily those of the company. This email and any files transmitted with it are confidential and solely for the use of the intended recipient
        or entity to whom they are addressed. It may contain material protected by attorney-client privilege. If you are not the intended recipient, or a person responsible for delivering to the intended recipient, be advised that you have received this email in error and that any use is strictly prohibited.

        Random House Group + 44 (0) 20 7840 8400
        http://www.randomhouse.co.uk
        http://www.booksattransworld.co.uk
        http://www.kidsatrandomhouse.co.uk
        Generic email address - enquiries@...

        Name & Registered Office:
        THE RANDOM HOUSE GROUP LIMITED
        20 VAUXHALL BRIDGE ROAD
        LONDON
        SW1V 2SA
        Random House Group Ltd is registered in the United Kingdom with company No. 00954009, VAT number 102838980
        ***********************************************************************************
      • binoy
        thanks mate thanks for the code. abhijit murade wrote: hi binoy, here with am sending some files which
        Message 3 of 7 , Feb 7, 2008
        • 0 Attachment
          thanks mate
          thanks for the code.


          abhijit murade <abhijitmurade@...> wrote: hi binoy,

          here with am sending some files which will help you to know working of
          webservice
          run these file in php environment and change the wsdl path as per
          environment.
          in these i have created WSDL which is required to access any webservice
          as u told client will be .Net, just u have to give web reference and paste
          WSDL url
          in address bar, simply call the method from your applicaion
          hope this will help u

          Regards,
          Abhijit Murade

          On 2/5/08, binoy <binoymvee@...> wrote:
          >
          > Hi Every one,
          > I want to write a web service.
          > server is php and cleint is .net.
          >
          > my requirement is that i want to return product list (all the product or
          > single product -- that depend on the id we are getting from client machine )
          > from an oscommerce site.the client is .net and the server is php.
          >
          > Actually i dont know anything abt the webservices. Can anybody help me.
          >
          >
          >
          >
          >
          > With Regards
          > Binoy.M.V
          >
          >
          > ---------------------------------
          > 5, 50, 500, 5000 - Store N number of mails in your inbox. Click here.
          >
          > [Non-text portions of this message have been removed]
          >
          >
          >

          --
          Thanks & Regards,

          ----------

          <?php

          /*
          $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $

          NuSOAP - Web Services Toolkit for PHP

          Copyright (c) 2002 NuSphere Corporation

          This library is free software; you can redistribute it and/or
          modify it under the terms of the GNU Lesser General Public
          License as published by the Free Software Foundation; either
          version 2.1 of the License, or (at your option) any later version.

          This library is distributed in the hope that it will be useful,
          but WITHOUT ANY WARRANTY; without even the implied warranty of
          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
          Lesser General Public License for more details.

          You should have received a copy of the GNU Lesser General Public
          License along with this library; if not, write to the Free Software
          Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

          If you have any questions or comments, please email:

          Dietrich Ayala
          dietrich@...
          http://dietrich.ganx4.com/nusoap

          NuSphere Corporation
          http://www.nusphere.com

          */

          /* load classes

          // necessary classes
          require_once('class.soapclient.php');
          require_once('class.soap_val.php');
          require_once('class.soap_parser.php');
          require_once('class.soap_fault.php');

          // transport classes
          require_once('class.soap_transport_http.php');

          // optional add-on classes
          require_once('class.xmlschema.php');
          require_once('class.wsdl.php');

          // server class
          require_once('class.soap_server.php');*/

          // class variable emulation
          // cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
          $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;

          /**
          *
          * nusoap_base
          *
          * @author Dietrich Ayala <dietrich@...>
          * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
          * @access public
          */
          class nusoap_base {
          /**
          * Identification for HTTP headers.
          *
          * @var string
          * @access private
          */
          var $title = 'NuSOAP';
          /**
          * Version for HTTP headers.
          *
          * @var string
          * @access private
          */
          var $version = '0.7.2';
          /**
          * CVS revision for HTTP headers.
          *
          * @var string
          * @access private
          */
          var $revision = '$Revision: 1.94 $';
          /**
          * Current error string (manipulated by getError/setError)
          *
          * @var string
          * @access private
          */
          var $error_str = '';
          /**
          * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
          *
          * @var string
          * @access private
          */
          var $debug_str = '';
          /**
          * toggles automatic encoding of special characters as entities
          * (should always be true, I think)
          *
          * @var boolean
          * @access private
          */
          var $charencoding = true;
          /**
          * the debug level for this instance
          *
          * @var integer
          * @access private
          */
          var $debugLevel;

          /**
          * set schema version
          *
          * @var string
          * @access public
          */
          var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';

          /**
          * charset encoding for outgoing messages
          *
          * @var string
          * @access public
          */
          var $soap_defencoding = 'ISO-8859-1';
          //var $soap_defencoding = 'UTF-8';

          /**
          * namespaces in an array of prefix => uri
          *
          * this is "seeded" by a set of constants, but it may be altered by code
          *
          * @var array
          * @access public
          */
          var $namespaces = array(
          'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
          'xsd' => 'http://www.w3.org/2001/XMLSchema',
          'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
          'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
          );

          /**
          * namespaces used in the current context, e.g. during serialization
          *
          * @var array
          * @access private
          */
          var $usedNamespaces = array();

          /**
          * XML Schema types in an array of uri => (array of xml type => php type)
          * is this legacy yet?
          * no, this is used by the xmlschema class to verify type => namespace mappings.
          * @var array
          * @access public
          */
          var $typemap = array(
          'http://www.w3.org/2001/XMLSchema' => array(
          'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
          'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
          'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
          // abstract "any" types
          'anyType'=>'string','anySimpleType'=>'string',
          // derived datatypes
          'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
          'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
          'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
          'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
          'http://www.w3.org/2000/10/XMLSchema' => array(
          'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
          'float'=>'double','dateTime'=>'string',
          'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
          'http://www.w3.org/1999/XMLSchema' => array(
          'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
          'float'=>'double','dateTime'=>'string',
          'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
          'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
          'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
          'http://xml.apache.org/xml-soap' => array('Map')
          );

          /**
          * XML entities to convert
          *
          * @var array
          * @access public
          * @deprecated
          * @see expandEntities
          */
          var $xmlEntities = array('quot' => '"','amp' => '&',
          'lt' => '<','gt' => '>','apos' => "'");

          /**
          * constructor
          *
          * @access public
          */
          function nusoap_base() {
          $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
          }

          /**
          * gets the global debug level, which applies to future instances
          *
          * @return integer Debug level 0-9, where 0 turns off
          * @access public
          */
          function getGlobalDebugLevel() {
          return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
          }

          /**
          * sets the global debug level, which applies to future instances
          *
          * @param int $level Debug level 0-9, where 0 turns off
          * @access public
          */
          function setGlobalDebugLevel($level) {
          $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
          }

          /**
          * gets the debug level for this instance
          *
          * @return int Debug level 0-9, where 0 turns off
          * @access public
          */
          function getDebugLevel() {
          return $this->debugLevel;
          }

          /**
          * sets the debug level for this instance
          *
          * @param int $level Debug level 0-9, where 0 turns off
          * @access public
          */
          function setDebugLevel($level) {
          $this->debugLevel = $level;
          }

          /**
          * adds debug data to the instance debug string with formatting
          *
          * @param string $string debug data
          * @access private
          */
          function debug($string){
          if ($this->debugLevel > 0) {
          $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
          }
          }

          /**
          * adds debug data to the instance debug string without formatting
          *
          * @param string $string debug data
          * @access public
          */
          function appendDebug($string){
          if ($this->debugLevel > 0) {
          // it would be nice to use a memory stream here to use
          // memory more efficiently
          $this->debug_str .= $string;
          }
          }

          /**
          * clears the current debug data for this instance
          *
          * @access public
          */
          function clearDebug() {
          // it would be nice to use a memory stream here to use
          // memory more efficiently
          $this->debug_str = '';
          }

          /**
          * gets the current debug data for this instance
          *
          * @return debug data
          * @access public
          */
          function &getDebug() {
          // it would be nice to use a memory stream here to use
          // memory more efficiently
          return $this->debug_str;
          }

          /**
          * gets the current debug data for this instance as an XML comment
          * this may change the contents of the debug data
          *
          * @return debug data as an XML comment
          * @access public
          */
          function &getDebugAsXMLComment() {
          // it would be nice to use a memory stream here to use
          // memory more efficiently
          while (strpos($this->debug_str, '--')) {
          $this->debug_str = str_replace('--', '- -', $this->debug_str);
          }
          return "<!--\n" . $this->debug_str . "\n-->";
          }

          /**
          * expands entities, e.g. changes '<' to '<'.
          *
          * @param string $val The string in which to expand entities.
          * @access private
          */
          function expandEntities($val) {
          if ($this->charencoding) {
          $val = str_replace('&', '&', $val);
          $val = str_replace("'", ''', $val);
          $val = str_replace('"', '"', $val);
          $val = str_replace('<', '<', $val);
          $val = str_replace('>', '>', $val);
          }
          return $val;
          }

          /**
          * returns error string if present
          *
          * @return mixed error string or false
          * @access public
          */
          function getError(){
          if($this->error_str != ''){
          return $this->error_str;
          }
          return false;
          }

          /**
          * sets error string
          *
          * @return boolean $string error string
          * @access private
          */
          function setError($str){
          $this->error_str = $str;
          }

          /**
          * detect if array is a simple array or a struct (associative array)
          *
          * @param mixed $val The PHP array
          * @return string (arraySimple|arrayStruct)
          * @access private
          */
          function isArraySimpleOrStruct($val) {
          $keyList = array_keys($val);
          foreach ($keyList as $keyListValue) {
          if (!is_int($keyListValue)) {
          return 'arrayStruct';
          }
          }
          return 'arraySimple';
          }

          /**
          * serializes PHP values in accordance w/ section 5. Type information is
          * not serialized if $use == 'literal'.
          *
          * @param mixed $val The value to serialize
          * @param string $name The name (local part) of the XML element
          * @param string $type The XML schema type (local part) for the element
          * @param string $name_ns The namespace for the name of the XML element
          * @param string $type_ns The namespace for the type of the element
          * @param array $attributes The attributes to serialize as name=>value pairs
          * @param string $use The WSDL "use" (encoded|literal)
          * @return string The serialized element, possibly with child elements
          * @access public
          */
          function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
          $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
          $this->appendDebug('value=' . $this->varDump($val));
          $this->appendDebug('attributes=' . $this->varDump($attributes));

          if(is_object($val) && get_class($val) == 'soapval'){
          return $val->serialize($use);
          }
          // force valid name if necessary
          if (is_numeric($name)) {
          $name = '__numeric_' . $name;
          } elseif (! $name) {
          $name = 'noname';
          }
          // if name has ns, add ns prefix to name
          $xmlns = '';
          if($name_ns){
          $prefix = 'nu'.rand(1000,9999);
          $name = $prefix.':'.$name;
          $xmlns .= " xmlns:$prefix=\"$name_ns\"";
          }
          // if type is prefixed, create type prefix
          if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
          // need to fix this. shouldn't default to xsd if no ns specified
          // w/o checking against typemap
          $type_prefix = 'xsd';
          } elseif($type_ns){
          $type_prefix = 'ns'.rand(1000,9999);
          $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
          }
          // serialize attributes if present
          $atts = '';
          if($attributes){
          foreach($attributes as $k => $v){
          $atts .= " $k=\"".$this->expandEntities($v).'"';
          }
          }
          // serialize null value
          if (is_null($val)) {
          if ($use == 'literal') {
          // TODO: depends on minOccurs
          return "<$name$xmlns $atts/>";
          } else {
          if (isset($type) && isset($type_prefix)) {
          $type_str = " xsi:type=\"$type_prefix:$type\"";
          } else {
          $type_str = '';
          }
          return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
          }
          }
          // serialize if an xsd built-in primitive type
          if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
          if (is_bool($val)) {
          if ($type == 'boolean') {
          $val = $val ? 'true' : 'false';
          } elseif (! $val) {
          $val = 0;
          }
          } else if (is_string($val)) {
          $val = $this->expandEntities($val);
          }
          if ($use == 'literal') {
          return "<$name$xmlns $atts>$val</$name>";
          } else {
          return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
          }
          }
          // detect type and serialize
          $xml = '';
          switch(true) {
          case (is_bool($val) || $type == 'boolean'):
          if ($type == 'boolean') {
          $val = $val ? 'true' : 'false';
          } elseif (! $val) {
          $val = 0;
          }
          if ($use == 'literal') {
          $xml .= "<$name$xmlns $atts>$val</$name>";
          } else {
          $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
          }
          break;
          case (is_int($val) || is_long($val) || $type == 'int'):
          if ($use == 'literal') {
          $xml .= "<$name$xmlns $atts>$val</$name>";
          } else {
          $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
          }
          break;
          case (is_float($val)|| is_double($val) || $type == 'float'):
          if ($use == 'literal') {
          $xml .= "<$name$xmlns $atts>$val</$name>";
          } else {
          $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
          }
          break;
          case (is_string($val) || $type == 'string'):
          $val = $this->expandEntities($val);
          if ($use == 'literal') {
          $xml .= "<$name$xmlns $atts>$val</$name>";
          } else {
          $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
          }
          break;
          case is_object($val):
          if (! $name) {
          $name = get_class($val);
          $this->debug("In serialize_val, used class name $name as element name");
          } else {
          $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
          }
          foreach(get_object_vars($val) as $k => $v){
          $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
          }
          $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
          break;
          break;
          case (is_array($val) || $type):
          // detect if struct or array
          $valueType = $this->isArraySimpleOrStruct($val);
          if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
          $i = 0;
          if(is_array($val) && count($val)> 0){
          foreach($val as $v){
          if(is_object($v) && get_class($v) == 'soapval'){
          $tt_ns = $v->type_ns;
          $tt = $v->type;
          } elseif (is_array($v)) {
          $tt = $this->isArraySimpleOrStruct($v);
          } else {
          $tt = gettype($v);
          }
          $array_types[$tt] = 1;
          // TODO: for literal, the name should be $name
          $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
          ++$i;
          }
          if(count($array_types) > 1){
          $array_typename = 'xsd:anyType';
          } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
          if ($tt == 'integer') {
          $tt = 'int';
          }
          $array_typename = 'xsd:'.$tt;
          } elseif(isset($tt) && $tt == 'arraySimple'){
          $array_typename = 'SOAP-ENC:Array';
          } elseif(isset($tt) && $tt == 'arrayStruct'){
          $array_typename = 'unnamed_struct_use_soapval';
          } else {
          // if type is prefixed, create type prefix
          if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
          $array_typename = 'xsd:' . $tt;
          } elseif ($tt_ns) {
          $tt_prefix = 'ns' . rand(1000, 9999);
          $array_typename = "$tt_prefix:$tt";
          $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
          } else {
          $array_typename = $tt;
          }
          }
          $array_type = $i;
          if ($use == 'literal') {
          $type_str = '';
          } else if (isset($type) && isset($type_prefix)) {
          $type_str = " xsi:type=\"$type_prefix:$type\"";
          } else {
          $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
          }
          // empty array
          } else {
          if ($use == 'literal') {
          $type_str = '';
          } else if (isset($type) && isset($type_prefix)) {
          $type_str = " xsi:type=\"$type_prefix:$type\"";
          } else {
          $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
          }
          }
          // TODO: for array in literal, there is no wrapper here
          $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
          } else {
          // got a struct
          if(isset($type) && isset($type_prefix)){
          $type_str = " xsi:type=\"$type_prefix:$type\"";
          } else {
          $type_str = '';
          }
          if ($use == 'literal') {
          $xml .= "<$name$xmlns $atts>";
          } else {
          $xml .= "<$name$xmlns$type_str$atts>";
          }
          foreach($val as $k => $v){
          // Apache Map
          if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
          $xml .= '<item>';
          $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
          $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
          $xml .= '</item>';
          } else {
          $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
          }
          }
          $xml .= "</$name>";
          }
          break;
          default:
          $xml .= 'not detected, got '.gettype($val).' for '.$val;
          break;
          }
          return $xml;
          }

          /**
          * serializes a message
          *
          * @param string $body the XML of the SOAP body
          * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
          * @param array $namespaces optional the namespaces used in generating the body and headers
          * @param string $style optional (rpc|document)
          * @param string $use optional (encoded|literal)
          * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
          * @return string the message
          * @access public
          */
          function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
          // TODO: add an option to automatically run utf8_encode on $body and $headers
          // if $this->soap_defencoding is UTF-8. Not doing this automatically allows
          // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1

          $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
          $this->debug("headers:");
          $this->appendDebug($this->varDump($headers));
          $this->debug("namespaces:");
          $this->appendDebug($this->varDump($namespaces));

          // serialize namespaces
          $ns_string = '';
          foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
          $ns_string .= " xmlns:$k=\"$v\"";
          }
          if($encodingStyle) {
          $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
          }

          // serialize headers
          if($headers){
          if (is_array($headers)) {
          $xml = '';
          foreach ($headers as $header) {
          $xml .= $this->serialize_val($header, false, false, false, false, false, $use);
          }
          $headers = $xml;
          $this->debug("In serializeEnvelope, serialzied array of headers to $headers");
          }
          $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
          }
          // serialize envelope
          return
          '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
          '<SOAP-ENV:Envelope'.$ns_string.">".
          $headers.
          "<SOAP-ENV:Body>".
          $body.
          "</SOAP-ENV:Body>".
          "</SOAP-ENV:Envelope>";
          }

          /**
          * formats a string to be inserted into an HTML stream
          *
          * @param string $str The string to format
          * @return string The formatted string
          * @access public
          * @deprecated
          */
          function formatDump($str){
          $str = htmlspecialchars($str);
          return nl2br($str);
          }

          /**
          * contracts (changes namespace to prefix) a qualified name
          *
          * @param string $qname qname
          * @return string contracted qname
          * @access private
          */
          function contractQname($qname){
          // get element namespace
          //$this->xdebug("Contract $qname");
          if (strrpos($qname, ':')) {
          // get unqualified name
          $name = substr($qname, strrpos($qname, ':') + 1);
          // get ns
          $ns = substr($qname, 0, strrpos($qname, ':'));
          $p = $this->getPrefixFromNamespace($ns);
          if ($p) {
          return $p . ':' . $name;
          }
          return $qname;
          } else {
          return $qname;
          }
          }

          /**
          * expands (changes prefix to namespace) a qualified name
          *
          * @param string $string qname
          * @return string expanded qname
          * @access private
          */
          function expandQname($qname){
          // get element prefix
          if(strpos($qname,':') && !ereg('^http://',$qname)){
          // get unqualified name
          $name = substr(strstr($qname,':'),1);
          // get ns prefix
          $prefix = substr($qname,0,strpos($qname,':'));
          if(isset($this->namespaces[$prefix])){
          return $this->namespaces[$prefix].':'.$name;
          } else {
          return $qname;
          }
          } else {
          return $qname;
          }
          }

          /**
          * returns the local part of a prefixed string
          * returns the original string, if not prefixed
          *
          * @param string $str The prefixed string
          * @return string The local part
          * @access public
          */
          function getLocalPart($str){
          if($sstr = strrchr($str,':')){
          // get unqualified name
          return substr( $sstr, 1 );
          } else {
          return $str;
          }
          }

          /**
          * returns the prefix part of a prefixed string
          * returns false, if not prefixed
          *
          * @param string $str The prefixed string
          * @return mixed The prefix or false if there is no prefix
          * @access public
          */
          function getPrefix($str){
          if($pos = strrpos($str,':')){
          // get prefix
          return substr($str,0,$pos);
          }
          return false;
          }

          /**
          * pass it a prefix, it returns a namespace
          *
          * @param string $prefix The prefix
          * @return mixed The namespace, false if no namespace has the specified prefix
          * @access public
          */
          function getNamespaceFromPrefix($prefix){
          if (isset($this->namespaces[$prefix])) {
          return $this->namespaces[$prefix];
          }
          //$this->setError("No namespace registered for prefix '$prefix'");
          return false;
          }

          /**
          * returns the prefix for a given namespace (or prefix)
          * or false if no prefixes registered for the given namespace
          *
          * @param string $ns The namespace
          * @return mixed The prefix, false if the namespace has no prefixes
          * @access public
          */
          function getPrefixFromNamespace($ns) {
          foreach ($this->namespaces as $p => $n) {
          if ($ns == $n || $ns == $p) {
          $this->usedNamespaces[$p] = $n;
          return $p;
          }
          }
          return false;
          }

          /**
          * returns the time in ODBC canonical form with microseconds
          *
          * @return string The time in ODBC canonical form with microseconds
          * @access public
          */
          function getmicrotime() {
          if (function_exists('gettimeofday')) {
          $tod = gettimeofday();
          $sec = $tod['sec'];
          $usec = $tod['usec'];
          } else {
          $sec = time();
          $usec = 0;
          }
          return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
          }

          /**
          * Returns a string with the output of var_dump
          *
          * @param mixed $data The variable to var_dump
          * @return string The output of var_dump
          * @access public
          */
          function varDump($data) {
          ob_start();
          var_dump($data);
          $ret_val = ob_get_contents();
          ob_end_clean();
          return $ret_val;
          }
          }

          // XML Schema Datatype Helper Functions

          //xsd:dateTime helpers

          /**
          * convert unix timestamp to ISO 8601 compliant date string
          *
          * @param string $timestamp Unix time stamp
          * @access public
          */
          function timestamp_to_iso8601($timestamp,$utc=true){
          $datestr = date('Y-m-d\TH:i:sO',$timestamp);
          if($utc){
          $eregStr =
          '([0-9]{4})-'. // centuries & years CCYY-
          '([0-9]{2})-'. // months MM-
          '([0-9]{2})'. // days DD
          'T'. // separator T
          '([0-9]{2}):'. // hours hh:
          '([0-9]{2}):'. // minutes mm:
          '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
          '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's

          if(ereg($eregStr,$datestr,$regs)){
          return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
          }
          return false;
          } else {
          return $datestr;
          }
          }

          /**
          * convert ISO 8601 compliant date string to unix timestamp
          *
          * @param string $datestr ISO 8601 compliant date string
          * @access public
          */
          function iso8601_to_timestamp($datestr){
          $eregStr =
          '([0-9]{4})-'. // centuries & years CCYY-
          '([0-9]{2})-'. // months MM-
          '([0-9]{2})'. // days DD
          'T'. // separator T
          '([0-9]{2}):'. // hours hh:
          '([0-9]{2}):'. // minutes mm:
          '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
          '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
          if(ereg($eregStr,$datestr,$regs)){
          // not utc
          if($regs[8] != 'Z'){
          $op = substr($regs[8],0,1);
          $h = substr($regs[8],1,2);
          $m = substr($regs[8],strlen($regs[8])-2,2);
          if($op == '-'){
          $regs[4] = $regs[4] + $h;
          $regs[5] = $regs[5] + $m;
          } elseif($op == '+'){
          $regs[4] = $regs[4] - $h;
          $regs[5] = $regs[5] - $m;
          }
          }
          return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
          } else {
          return false;
          }
          }

          /**
          * sleeps some number of microseconds
          *
          * @param string $usec the number of microseconds to sleep
          * @access public
          * @deprecated
          */
          function usleepWindows($usec)
          {
          $start = gettimeofday();

          do
          {
          $stop = gettimeofday();
          $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
          + $stop['usec'] - $start['usec'];
          }
          while ($timePassed < $usec);
          }

          ?><?php



          /**
          * Contains information for a SOAP fault.
          * Mainly used for returning faults from deployed functions
          * in a server instance.
          * @author Dietrich Ayala <dietrich@...>
          * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
          * @access public
          */
          class soap_fault extends nusoap_base {
          /**
          * The fault code (client|server)
          * @var string
          * @access private
          */
          var $faultcode;
          /**
          * The fault actor
          * @var string
          * @access private
          */
          var $faultactor;
          /**
          * The fault string, a description of the fault
          * @var string
          * @access private
          */
          var $faultstring;
          /**
          * The fault detail, typically a string or array of string
          * @var mixed
          * @access private
          */
          var $faultdetail;

          /**
          * constructor
          *
          * @param string $faultcode (client | server)
          * @param string $faultactor only used when msg routed between multiple actors
          * @param string $faultstring human readable error message
          * @param mixed $faultdetail detail, typically a string or array of string
          */
          function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
          parent::nusoap_base();
          $this->faultcode = $faultcode;
          $this->faultactor = $faultactor;
          $this->faultstring = $faultstring;
          $this->faultdetail = $faultdetail;
          }

          /**
          * serialize a fault
          *
          * @return string The serialization of the fault instance.
          * @access public
          */
          function serialize(){
          $ns_string = '';
          foreach($this->namespaces as $k => $v){
          $ns_string .= "\n xmlns:$k=\"$v\"";
          }
          $return_msg =
          '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
          '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
          '<SOAP-ENV:Body>'.
          '<SOAP-ENV:Fault>'.
          $this->serialize_val($this->faultcode, 'faultcode').
          $this->serialize_val($this->faultactor, 'faultactor').
          $this->serialize_val($this->faultstring, 'faultstring').
          $this->serialize_val($this->faultdetail, 'detail').
          '</SOAP-ENV:Fault>'.
          '</SOAP-ENV:Body>'.
          '</SOAP-ENV:Envelope>';
          return $return_msg;
          }
          }



          ?><?php



          /**
          * parses an XML Schema, allows access to it's data, other utility methods
          * no validation... yet.
          * very experimental and limited. As is discussed on XML-DEV, I'm one of the people
          * that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
          * tutorials I refer to :)
          *
          * @author Dietrich Ayala <dietrich@...>
          * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
          * @access public
          */
          class XMLSchema extends nusoap_base {

          // files
          var $schema = '';
          var $xml = '';
          // namespaces
          var $enclosingNamespaces;
          // schema info
          var $schemaInfo = array();
          var $schemaTargetNamespace = '';
          // types, elements, attributes defined by the schema
          var $attributes = array();
          var $complexTypes = array();
          var $complexTypeStack = array();
          var $currentComplexType = null;
          var $elements = array();
          var $elementStack = array();
          var $currentElement = null;
          var $simpleTypes = array();
          var $simpleTypeStack = array();
          var $currentSimpleType = null;
          // imports
          var $imports = array();
          // parser vars
          var $parser;
          var $position = 0;
          var $depth = 0;
          var $depth_array = array();
          var $message = array();
          var $defaultNamespace = array();

          /**
          * constructor
          *
          * @param string $schema schema document URI
          * @param string $xml xml document URI
          * @param string $namespaces namespaces defined in enclosing XML
          * @access public
          */
          function XMLSchema($schema='',$xml='',$namespaces=array()){
          parent::nusoap_base();
          $this->debug('xmlschema class instantiated, inside constructor');
          // files
          $this->schema = $schema;
          $this->xml = $xml;

          // namespaces
          $this->enclosingNamespaces = $namespaces;
          $this->namespaces = array_merge($this->namespaces, $namespaces);

          // parse schema file
          if($schema != ''){
          $this->debug('initial schema file: '.$schema);
          $this->parseFile($schema, 'schema');
          }

          // parse xml file
          if($xml != ''){
          $this->debug('initial xml file: '.$xml);
          $this->parseFile($xml, 'xml');
          }

          }

          /**
          * parse an XML file
          *
          * @param string $xml, path/URL to XML file
          * @param string $type, (schema | xml)
          * @return boolean
          * @access public
          */
          function parseFile($xml,$type){
          // parse xml file
          if($xml != ""){
          $xmlStr = @join("",@file($xml));
          if($xmlStr == ""){
          $msg = 'Error reading XML from '.$xml;
          $this->setError($msg);
          $this->debug($msg);
          return false;
          } else {
          $this->debug("parsing $xml");
          $this->parseString($xmlStr,$type);
          $this->debug("done parsing $xml");
          return true;
          }
          }
          return false;
          }

          /**
          * parse an XML string
          *
          * @param string $xml path or URL
          * @param string $type, (schema|xml)
          * @access private
          */
          function parseString($xml,$type){
          // parse xml string
          if($xml != ""){

          // Create an XML parser.
          $this->parser = xml_parser_create();
          // Set the options for parsing the XML data.
          xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);

          // Set the object for the parser.
          xml_set_object($this->parser, $this);

          // Set the element handlers for the parser.
          if($type == "schema"){
          xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
          xml_set_character_data_handler($this->parser,'schemaCharacterData');
          } elseif($type == "xml"){
          xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
          xml_set_character_data_handler($this->parser,'xmlCharacterData');
          }

          // Parse the XML file.
          if(!xml_parse($this->parser,$xml,true)){
          // Display an error message.
          $errstr = sprintf('XML error parsing XML schema on line %d: %s',
          xml_get_current_line_number($this->parser),
          xml_error_string(xml_get_error_code($this->parser))
          );
          $this->debug($errstr);
          $this->debug("XML payload:\n" . $xml);
          $this->setError($errstr);
          }

          xml_parser_free($this->parser);
          } else{
          $this->debug('no xml passed to parseString()!!');
          $this->setError('no xml passed to parseString()!!');
          }
          }

          /**
          * start-element handler
          *
          * @param string $parser XML parser object
          * @param string $name element name
          * @param string $attrs associative array of attributes
          * @access private
          */
          function schemaStartElement($parser, $name, $attrs) {

          // position in the total number of elements, starting from 0
          $pos = $this->position++;
          $depth = $this->depth++;
          // set self as current value for this depth
          $this->depth_array[$depth] = $pos;
          $this->message[$pos] = array('cdata' => '');
          if ($depth > 0) {
          $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
          } else {
          $this->defaultNamespace[$pos] = false;
          }

          // get element prefix
          if($prefix = $this->getPrefix($name)){
          // get unqualified name
          $name = $this->getLocalPart($name);
          } else {
          $prefix = '';
          }

          // loop thru attributes, expanding, and registering namespace declarations
          if(count($attrs) > 0){
          foreach($attrs as $k => $v){
          // if ns declarations, add to class level array of valid namespaces
          if(ereg("^xmlns",$k)){
          //$this->xdebug("$k: $v");
          //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
          if($ns_prefix = substr(strrchr($k,':'),1)){
          //$this->xdebug("Add namespace[$ns_prefix] = $v");
          $this->namespaces[$ns_prefix] = $v;
          } else {
          $this->defaultNamespace[$pos] = $v;
          if (! $this->getPrefixFromNamespace($v)) {
          $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
          }
          }
          if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
          $this->XMLSchemaVersion = $v;
          $this->namespaces['xsi'] = $v.'-instance';
          }
          }
          }
          foreach($attrs as $k => $v){
          // expand each attribute
          $k = strpos($k,':') ? $this->expandQname($k) : $k;
          $v = strpos($v,':') ? $this->expandQname($v) : $v;
          $eAttrs[$k] = $v;
          }
          $attrs = $eAttrs;
          } else {
          $attrs = array();
          }
          // find status, register data
          switch($name){
          case 'all': // (optional) compositor content for a complexType
          case 'choice':
          case 'group':
          case 'sequence':
          //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
          $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
          //if($name == 'all' || $name == 'sequence'){
          // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
          //}
          break;
          case 'attribute': // complexType attribute
          //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
          $this->xdebug("parsing attribute:");
          $this->appendDebug($this->varDump($attrs));
          if (!isset($attrs['form'])) {
          $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
          }
          if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
          $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
          if (!strpos($v, ':')) {
          // no namespace in arrayType attribute value...
          if ($this->defaultNamespace[$pos]) {
          // ...so use the default
          $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
          }
          }
          }
          if(isset($attrs['name'])){
          $this->attributes[$attrs['name']] = $attrs;
          $aname = $attrs['name'];
          } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
          if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
          $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
          } else {
          $aname = '';
          }
          } elseif(isset($attrs['ref'])){
          $aname = $attrs['ref'];
          $this->attributes[$attrs['ref']] = $attrs;
          }

          if($this->currentComplexType){ // This should *always* be
          $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
          }
          // arrayType attribute
          if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
          $prefix = $this->getPrefix($aname);
          if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
          $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
          } else {
          $v = '';
          }
          if(strpos($v,'[,]')){
          $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
          }
          $v = substr($v,0,strpos($v,'[')); // clip the []
          if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
          $v = $this->XMLSchemaVersion.':'.$v;
          }
          $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
          }
          break;
          case 'complexContent': // (optional) content for a complexType
          break;
          case 'complexType':
          array_push($this->complexTypeStack, $this->currentComplexType);
          if(isset($attrs['name'])){
          $this->xdebug('processing named complexType '.$attrs['name']);
          //$this->currentElement = false;
          $this->currentComplexType = $attrs['name'];
          $this->complexTypes[$this->currentComplexType] = $attrs;
          $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
          // This is for constructs like
          // <complexType name="ListOfString" base="soap:Array">
          // <sequence>
          // <element name="string" type="xsd:string"
          // minOccurs="0" maxOccurs="unbounded" />
          // </sequence>
          // </complexType>
          if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
          $this->xdebug('complexType is unusual array');
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
          } else {
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
          }
          }else{
          $this->xdebug('processing unnamed complexType for element '.$this->currentElement);
          $this->currentComplexType = $this->currentElement . '_ContainedType';
          //$this->currentElement = false;
          $this->complexTypes[$this->currentComplexType] = $attrs;
          $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
          // This is for constructs like
          // <complexType name="ListOfString" base="soap:Array">
          // <sequence>
          // <element name="string" type="xsd:string"
          // minOccurs="0" maxOccurs="unbounded" />
          // </sequence>
          // </complexType>
          if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
          $this->xdebug('complexType is unusual array');
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
          } else {
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
          }
          }
          break;
          case 'element':
          array_push($this->elementStack, $this->currentElement);
          // elements defined as part of a complex type should
          // not really be added to $this->elements, but for some
          // reason, they are
          if (!isset($attrs['form'])) {
          $attrs['form'] = $this->schemaInfo['elementFormDefault'];
          }
          if(isset($attrs['type'])){
          $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
          if (! $this->getPrefix($attrs['type'])) {
          if ($this->defaultNamespace[$pos]) {
          $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
          $this->xdebug('used default namespace to make type ' . $attrs['type']);
          }
          }
          // This is for constructs like
          // <complexType name="ListOfString" base="soap:Array">
          // <sequence>
          // <element name="string" type="xsd:string"
          // minOccurs="0" maxOccurs="unbounded" />
          // </sequence>
          // </complexType>
          if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
          $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
          $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
          }
          $this->currentElement = $attrs['name'];
          $this->elements[ $attrs['name'] ] = $attrs;
          $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
          $ename = $attrs['name'];
          } elseif(isset($attrs['ref'])){
          $this->xdebug("processing element as ref to ".$attrs['ref']);
          $this->currentElement = "ref to ".$attrs['ref'];
          $ename = $this->getLocalPart($attrs['ref']);
          } else {
          $this->xdebug("processing untyped element ".$attrs['name']);
          $this->currentElement = $attrs['name'];
          $this->elements[ $attrs['name'] ] = $attrs;
          $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
          $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
          $this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
          $ename = $attrs['name'];
          }
          if(isset($ename) && $this->currentComplexType){
          $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
          }
          break;
          case 'enumeration': // restriction value list member
          $this->xdebug('enumeration ' . $attrs['value']);
          if ($this->currentSimpleType) {
          $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
          } elseif ($this->currentComplexType) {
          $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
          }
          break;
          case 'extension': // simpleContent or complexContent type extension
          $this->xdebug('extension ' . $attrs['base']);
          if ($this->currentComplexType) {
          $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
          }
          break;
          case 'import':
          if (isset($attrs['schemaLocation'])) {
          //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
          $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
          } else {
          //$this->xdebug('import namespace ' . $attrs['namespace']);
          $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
          if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
          $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
          }
          }
          break;
          case 'list': // simpleType value list
          break;
          case 'restriction': // simpleType, simpleContent or complexContent value restriction
          $this->xdebug('restriction ' . $attrs['base']);
          if($this->currentSimpleType){
          $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
          } elseif($this->currentComplexType){
          $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
          if(strstr($attrs['base'],':') == ':Array'){
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
          }
          }
          break;
          case 'schema':
          $this->schemaInfo = $attrs;
          $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
          if (isset($attrs['targetNamespace'])) {
          $this->schemaTargetNamespace = $attrs['targetNamespace'];
          }
          if (!isset($attrs['elementFormDefault'])) {
          $this->schemaInfo['elementFormDefault'] = 'unqualified';
          }
          if (!isset($attrs['attributeFormDefault'])) {
          $this->schemaInfo['attributeFormDefault'] = 'unqualified';
          }
          break;
          case 'simpleContent': // (optional) content for a complexType
          break;
          case 'simpleType':
          array_push($this->simpleTypeStack, $this->currentSimpleType);
          if(isset($attrs['name'])){
          $this->xdebug("processing simpleType for name " . $attrs['name']);
          $this->currentSimpleType = $attrs['name'];
          $this->simpleTypes[ $attrs['name'] ] = $attrs;
          $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
          $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
          } else {
          $this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
          $this->currentSimpleType = $this->currentElement . '_ContainedType';
          //$this->currentElement = false;
          $this->simpleTypes[$this->currentSimpleType] = $attrs;
          $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
          }
          break;
          case 'union': // simpleType type list
          break;
          default:
          //$this->xdebug("do not have anything to do for element $name");
          }
          }

          /**
          * end-element handler
          *
          * @param string $parser XML parser object
          * @param string $name element name
          * @access private
          */
          function schemaEndElement($parser, $name) {
          // bring depth down a notch
          $this->depth--;
          // position of current element is equal to the last value left in depth_array for my depth
          if(isset($this->depth_array[$this->depth])){
          $pos = $this->depth_array[$this->depth];
          }
          // get element prefix
          if ($prefix = $this->getPrefix($name)){
          // get unqualified name
          $name = $this->getLocalPart($name);
          } else {
          $prefix = '';
          }
          // move on...
          if($name == 'complexType'){
          $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
          $this->currentComplexType = array_pop($this->complexTypeStack);
          //$this->currentElement = false;
          }
          if($name == 'element'){
          $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
          $this->currentElement = array_pop($this->elementStack);
          }
          if($name == 'simpleType'){
          $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
          $this->currentSimpleType = array_pop($this->simpleTypeStack);
          }
          }

          /**
          * element content handler
          *
          * @param string $parser XML parser object
          * @param string $data element content
          * @access private
          */
          function schemaCharacterData($parser, $data){
          $pos = $this->depth_array[$this->depth - 1];
          $this->message[$pos]['cdata'] .= $data;
          }

          /**
          * serialize the schema
          *
          * @access public
          */
          function serializeSchema(){

          $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
          $xml = '';
          // imports
          if (sizeof($this->imports) > 0) {
          foreach($this->imports as $ns => $list) {
          foreach ($list as $ii) {
          if ($ii['location'] != '') {
          $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
          } else {
          $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
          }
          }
          }
          }
          // complex types
          foreach($this->complexTypes as $typeName => $attrs){
          $contentStr = '';
          // serialize child elements
          if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
          foreach($attrs['elements'] as $element => $eParts){
          if(isset($eParts['ref'])){
          $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
          } else {
          $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
          foreach ($eParts as $aName => $aValue) {
          // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
          if ($aName != 'name' && $aName != 'type') {
          $contentStr .= " $aName=\"$aValue\"";
          }
          }
          $contentStr .= "/>\n";
          }
          }
          // compositor wraps elements
          if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
          $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
          }
          }
          // attributes
          if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
          foreach($attrs['attrs'] as $attr => $aParts){
          $contentStr .= " <$schemaPrefix:attribute";
          foreach ($aParts as $a => $v) {
          if ($a == 'ref' || $a == 'type') {
          $contentStr .= " $a=\"".$this->contractQName($v).'"';
          } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
          $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
          $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
          } else {
          $contentStr .= " $a=\"$v\"";
          }
          }
          $contentStr .= "/>\n";
          }
          }
          // if restriction
          if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
          $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
          // complex or simple content
          if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
          $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
          }
          }
          // finalize complex type
          if($contentStr != ''){
          $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
          } else {
          $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
          }
          $xml .= $contentStr;
          }
          // simple types
          if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
          foreach($this->simpleTypes as $typeName => $eParts){
          $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
          if (isset($eParts['enumeration'])) {
          foreach ($eParts['enumeration'] as $e) {
          $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
          }
          }
          $xml .= " </$schemaPrefix:simpleType>";
          }
          }
          // elements
          if(isset($this->elements) && count($this->elements) > 0){
          foreach($this->elements as $element => $eParts){
          $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
          }
          }
          // attributes
          if(isset($this->attributes) && count($this->attributes) > 0){
          foreach($this->attributes as $attr => $aParts){
          $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
          }
          }
          // finish 'er up
          $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
          foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
          $el .= " xmlns:$nsp=\"$ns\"\n";
          }
          $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
          return $xml;
          }

          /**
          * adds debug data to the clas level debug string
          *
          * @param string $string debug data
          * @access private
          */
          function xdebug($string){
          $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
          }

          /**
          * get the PHP type of a user defined type in the schema
          * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
          * returns false if no type exists, or not w/ the given namespace
          * else returns a string that is either a native php type, or 'struct'
          *
          * @param string $type, name of defined type
          * @param string $ns, namespace of type
          * @return mixed
          * @access public
          * @deprecated
          */
          function getPHPType($type,$ns){
          if(isset($this->typemap[$ns][$type])){
          //print "found type '$type' and ns $ns in typemap<br>";
          return $this->typemap[$ns][$type];
          } elseif(isset($this->complexTypes[$type])){
          //print "getting type '$type' and ns $ns from complexTypes array<br>";
          return $this->complexTypes[$type]['phpType'];
          }
          return false;
          }

          /**
          * returns an associative array of information about a given type
          * returns false if no type exists by the given name
          *
          * For a complexType typeDef = array(
          * 'restrictionBase' => '',
          * 'phpType' => '',
          * 'compositor' => '(sequence|all)',
          * 'elements' => array(), // refs to elements array
          * 'attrs' => array() // refs to attributes array
          * ... and so on (see addComplexType)
          * )
          *
          * For simpleType or element, the array has different keys.
          *
          * @param string
          * @return mixed
          * @access public
          * @see addComplexType
          * @see addSimpleType
          * @see addElement
          */
          function getTypeDef($type){
          //$this->debug("in getTypeDef for type $type");
          if(isset($this->complexTypes[$type])){
          $this->xdebug("in getTypeDef, found complexType $type");
          return $this->complexTypes[$type];
          } elseif(isset($this->simpleTypes[$type])){
          $this->xdebug("in getTypeDef, found simpleType $type");
          if (!isset($this->simpleTypes[$type]['phpType'])) {
          // get info for type to tack onto the simple type
          // TODO: can this ever really apply (i.e. what is a simpleType really?)
          $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
          $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
          $etype = $this->getTypeDef($uqType);
          if ($etype) {
          $this->xdebug("in getTypeDef, found type for simpleType $type:");
          $this->xdebug($this->varDump($etype));
          if (isset($etype['phpType'])) {
          $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
          }
          if (isset($etype['elements'])) {
          $this->simpleTypes[$type]['elements'] = $etype['elements'];
          }
          }
          }
          return $this->simpleTypes[$type];
          } elseif(isset($this->elements[$type])){
          $this->xdebug("in getTypeDef, found element $type");
          if (!isset($this->elements[$type]['phpType'])) {
          // get info for type to tack onto the element
          $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
          $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
          $etype = $this->getTypeDef($uqType);
          if ($etype) {
          $this->xdebug("in getTypeDef, found type for element $type:");
          $this->xdebug($this->varDump($etype));
          if (isset($etype['phpType'])) {
          $this->elements[$type]['phpType'] = $etype['phpType'];
          }
          if (isset($etype['elements'])) {
          $this->elements[$type]['elements'] = $etype['elements'];
          }
          } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
          $this->xdebug("in getTypeDef, element $type is an XSD type");
          $this->elements[$type]['phpType'] = 'scalar';
          }
          }
          return $this->elements[$type];
          } elseif(isset($this->attributes[$type])){
          $this->xdebug("in getTypeDef, found attribute $type");
          return $this->attributes[$type];
          } elseif (ereg('_ContainedType$', $type)) {
          $this->xdebug("in getTypeDef, have an untyped element $type");
          $typeDef['typeClass'] = 'simpleType';
          $typeDef['phpType'] = 'scalar';
          $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
          return $typeDef;
          }
          $this->xdebug("in getTypeDef, did not find $type");
          return false;
          }

          /**
          * returns a sample serialization of a given type, or false if no type by the given name
          *
          * @param string $type, name of type
          * @return mixed
          * @access public
          * @deprecated
          */
          function serializeTypeDef($type){
          //print "in sTD() for type $type<br>";
          if($typeDef = $this->getTypeDef($type)){
          $str .= '<'.$type;
          if(is_array($typeDef['attrs'])){
          foreach($attrs as $attName => $data){
          $str .= " $attName=\"{type = ".$data['type']."}\"";
          }
          }
          $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
          if(count($typeDef['elements']) > 0){
          $str .= ">";
          foreach($typeDef['elements'] as $element => $eData){
          $str .= $this->serializeTypeDef($element);
          }
          $str .= "</$type>";
          } elseif($typeDef['typeClass'] == 'element') {
          $str .= "></$type>";
          } else {
          $str .= "/>";
          }
          return $str;
          }
          return false;
          }

          /**
          * returns HTML form elements that allow a user
          * to enter values for creating an instance of the given type.
          *
          * @param string $name, name for type instance
          * @param string $type, name of type
          * @return string
          * @access public
          * @deprecated
          */
          function typeToForm($name,$type){
          // get typedef
          if($typeDef = $this->getTypeDef($type)){
          // if struct
          if($typeDef['phpType'] == 'struct'){
          $buffer .= '<table>';
          foreach($typeDef['elements'] as $child => $childDef){
          $buffer .= "
          <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
          <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
          }
          $buffer .= '</table>';
          // if array
          } elseif($typeDef['phpType'] == 'array'){
          $buffer .= '<table>';
          for($i=0;$i < 3; $i++){
          $buffer .= "
          <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
          <td><input type='text' name='parameters[".$name."][]'></td></tr>";
          }
          $buffer .= '</table>';
          // if scalar
          } else {
          $buffer .= "<input type='text' name='parameters[$name]'>";
          }
          } else {
          $buffer .= "<input type='text' name='parameters[$name]'>";
          }
          return $buffer;
          }

          /**
          * adds a complex type to the schema
          *
          * example: array
          *
          * addType(
          * 'ArrayOfstring',
          * 'complexType',
          * 'array',
          * '',
          * 'SOAP-ENC:Array',
          * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
          * 'xsd:string'
          * );
          *
          * example: PHP associative array ( SOAP Struct )
          *
          * addType(
          * 'SOAPStruct',
          * 'complexType',
          * 'struct',
          * 'all',
          * array('myVar'=> array('name'=>'myVar','type'=>'string')
          * );
          *
          * @param name
          * @param typeClass (complexType|simpleType|attribute)
          * @param phpType: currently supported are array and struct (php assoc array)
          * @param compositor (all|sequence|choice)
          * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
          * @param elements = array ( name = array(name=>'',type=>'') )
          * @param attrs = array(
          * array(
          * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
          * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
          * )
          * )
          * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
          * @access public
          * @see getTypeDef
          */
          function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
          $this->complexTypes[$name] = array(
          'name' => $name,
          'typeClass' => $typeClass,
          'phpType' => $phpType,
          'compositor'=> $compositor,
          'restrictionBase' => $restrictionBase,
          'elements' => $elements,
          'attrs' => $attrs,
          'arrayType' => $arrayType
          );

          $this->xdebug("addComplexType $name:");
          $this->appendDebug($this->varDump($this->complexTypes[$name]));
          }

          /**
          * adds a simple type to the schema
          *
          * @param string $name
          * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
          * @param string $typeClass (should always be simpleType)
          * @param string $phpType (should always be scalar)
          * @param array $enumeration array of values
          * @access public
          * @see xmlschema
          * @see getTypeDef
          */
          function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
          $this->simpleTypes[$name] = array(
          'name' => $name,
          'typeClass' => $typeClass,
          'phpType' => $phpType,
          'type' => $restrictionBase,
          'enumeration' => $enumeration
          );

          $this->xdebug("addSimpleType $name:");
          $this->appendDebug($this->varDump($this->simpleTypes[$name]));
          }

          /**
          * adds an element to the schema
          *
          * @param array $attrs attributes that must include name and type
          * @see xmlschema
          * @access public
          */
          function addElement($attrs) {
          if (! $this->getPrefix($attrs['type'])) {
          $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
          }
          $this->elements[ $attrs['name'] ] = $attrs;
          $this->elements[ $attrs['name'] ]['typeClass'] = 'element';

          $this->xdebug("addElement " . $attrs['name']);
          $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
          }
          }



          ?><?php



          /**
          * For creating serializable abstractions of native PHP types. This class
          * allows element name/namespace, XSD type, and XML attributes to be
          * associated with a value. This is extremely useful when WSDL is not
          * used, but is also useful when WSDL is used with polymorphic types, including
          * xsd:anyType and user-defined types.
          *
          * @author Dietrich Ayala <dietrich@...>
          * @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
          * @access public
          */
          class soapval extends nusoap_base {
          /**
          * The XML element name
          *
          * @var string
          * @access private
          */
          var $name;
          /**
          * The XML type name (string or false)
          *
          * @var mixed
          * @access private
          */
          var $type;
          /**
          * The PHP value
          *
          * @var mixed
          * @access private
          */
          var $value;
          /**
          * The XML element namespace (string or false)
          *
          * @var mixed
          * @access private
          */
          var $element_ns;
          /**
          * The XML type namespace (string or false)
          *
          * @var mixed
          * @access private
          */
          var $type_ns;
          /**
          * The XML element attributes (array or false)
          *
          * @var mixed
          * @access private
          */
          var $attributes;

          /**
          * constructor
          *
          * @param string $name optional name
          * @param mixed $type optional type name
          * @param mixed $value optional value
          * @param mixed $element_ns optional namespace of value
          * @param mixed $type_ns optional namespace of type
          * @param mixed $attributes associative array of attributes to add to element serialization
          * @access public
          */
          function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
          parent::nusoap_base();
          $this->name = $name;
          $this->type = $type;
          $this->value = $value;
          $this->element_ns = $element_ns;
          $this->type_ns = $type_ns;
          $this->attrib<br/><br/>(Message over 64 KB, truncated)
        Your message has been successfully submitted and would be delivered to recipients shortly.