[ Index ]
 

Code source de Mantis 1.1.0rc3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/api/soap/nusoap/ -> class.xmlschema.php (source)

   1  <?php
   2  
   3  
   4  
   5  
   6  /**

   7  * parses an XML Schema, allows access to it's data, other utility methods.

   8  * imperfect, no validation... yet, but quite functional.

   9  *

  10  * @author   Dietrich Ayala <dietrich@ganx4.com>

  11  * @author   Scott Nichol <snichol@users.sourceforge.net>

  12  * @version  $Id: class.xmlschema.php,v 1.49 2007/11/06 14:17:53 snichol Exp $

  13  * @access   public

  14  */
  15  class nusoap_xmlschema extends nusoap_base  {
  16      
  17      // files

  18      var $schema = '';
  19      var $xml = '';
  20      // namespaces

  21      var $enclosingNamespaces;
  22      // schema info

  23      var $schemaInfo = array();
  24      var $schemaTargetNamespace = '';
  25      // types, elements, attributes defined by the schema

  26      var $attributes = array();
  27      var $complexTypes = array();
  28      var $complexTypeStack = array();
  29      var $currentComplexType = null;
  30      var $elements = array();
  31      var $elementStack = array();
  32      var $currentElement = null;
  33      var $simpleTypes = array();
  34      var $simpleTypeStack = array();
  35      var $currentSimpleType = null;
  36      // imports

  37      var $imports = array();
  38      // parser vars

  39      var $parser;
  40      var $position = 0;
  41      var $depth = 0;
  42      var $depth_array = array();
  43      var $message = array();
  44      var $defaultNamespace = array();
  45      
  46      /**

  47      * constructor

  48      *

  49      * @param    string $schema schema document URI

  50      * @param    string $xml xml document URI

  51      * @param    string $namespaces namespaces defined in enclosing XML

  52      * @access   public

  53      */
  54  	function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
  55          parent::nusoap_base();
  56          $this->debug('nusoap_xmlschema class instantiated, inside constructor');
  57          // files

  58          $this->schema = $schema;
  59          $this->xml = $xml;
  60  
  61          // namespaces

  62          $this->enclosingNamespaces = $namespaces;
  63          $this->namespaces = array_merge($this->namespaces, $namespaces);
  64  
  65          // parse schema file

  66          if($schema != ''){
  67              $this->debug('initial schema file: '.$schema);
  68              $this->parseFile($schema, 'schema');
  69          }
  70  
  71          // parse xml file

  72          if($xml != ''){
  73              $this->debug('initial xml file: '.$xml);
  74              $this->parseFile($xml, 'xml');
  75          }
  76  
  77      }
  78  
  79      /**

  80      * parse an XML file

  81      *

  82      * @param string $xml path/URL to XML file

  83      * @param string $type (schema | xml)

  84      * @return boolean

  85      * @access public

  86      */
  87  	function parseFile($xml,$type){
  88          // parse xml file

  89          if($xml != ""){
  90              $xmlStr = @join("",@file($xml));
  91              if($xmlStr == ""){
  92                  $msg = 'Error reading XML from '.$xml;
  93                  $this->setError($msg);
  94                  $this->debug($msg);
  95              return false;
  96              } else {
  97                  $this->debug("parsing $xml");
  98                  $this->parseString($xmlStr,$type);
  99                  $this->debug("done parsing $xml");
 100              return true;
 101              }
 102          }
 103          return false;
 104      }
 105  
 106      /**

 107      * parse an XML string

 108      *

 109      * @param    string $xml path or URL

 110      * @param    string $type (schema|xml)

 111      * @access   private

 112      */
 113  	function parseString($xml,$type){
 114          // parse xml string

 115          if($xml != ""){
 116  
 117              // Create an XML parser.

 118              $this->parser = xml_parser_create();
 119              // Set the options for parsing the XML data.

 120              xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
 121  
 122              // Set the object for the parser.

 123              xml_set_object($this->parser, $this);
 124  
 125              // Set the element handlers for the parser.

 126              if($type == "schema"){
 127                  xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
 128                  xml_set_character_data_handler($this->parser,'schemaCharacterData');
 129              } elseif($type == "xml"){
 130                  xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
 131                  xml_set_character_data_handler($this->parser,'xmlCharacterData');
 132              }
 133  
 134              // Parse the XML file.

 135              if(!xml_parse($this->parser,$xml,true)){
 136              // Display an error message.

 137                  $errstr = sprintf('XML error parsing XML schema on line %d: %s',
 138                  xml_get_current_line_number($this->parser),
 139                  xml_error_string(xml_get_error_code($this->parser))
 140                  );
 141                  $this->debug($errstr);
 142                  $this->debug("XML payload:\n" . $xml);
 143                  $this->setError($errstr);
 144              }
 145              
 146              xml_parser_free($this->parser);
 147          } else{
 148              $this->debug('no xml passed to parseString()!!');
 149              $this->setError('no xml passed to parseString()!!');
 150          }
 151      }
 152  
 153      /**

 154       * gets a type name for an unnamed type

 155       *

 156       * @param    string    Element name

 157       * @return    string    A type name for an unnamed type

 158       * @access    private

 159       */
 160  	function CreateTypeName($ename) {
 161          $scope = '';
 162          for ($i = 0; $i < count($this->complexTypeStack); $i++) {
 163              $scope .= $this->complexTypeStack[$i] . '_';
 164          }
 165          return $scope . $ename . '_ContainedType';
 166      }
 167      
 168      /**

 169      * start-element handler

 170      *

 171      * @param    string $parser XML parser object

 172      * @param    string $name element name

 173      * @param    string $attrs associative array of attributes

 174      * @access   private

 175      */
 176  	function schemaStartElement($parser, $name, $attrs) {
 177          
 178          // position in the total number of elements, starting from 0

 179          $pos = $this->position++;
 180          $depth = $this->depth++;
 181          // set self as current value for this depth

 182          $this->depth_array[$depth] = $pos;
 183          $this->message[$pos] = array('cdata' => ''); 
 184          if ($depth > 0) {
 185              $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
 186          } else {
 187              $this->defaultNamespace[$pos] = false;
 188          }
 189  
 190          // get element prefix

 191          if($prefix = $this->getPrefix($name)){
 192              // get unqualified name

 193              $name = $this->getLocalPart($name);
 194          } else {
 195              $prefix = '';
 196          }
 197          
 198          // loop thru attributes, expanding, and registering namespace declarations

 199          if(count($attrs) > 0){
 200              foreach($attrs as $k => $v){
 201                  // if ns declarations, add to class level array of valid namespaces

 202                  if(ereg("^xmlns",$k)){
 203                      //$this->xdebug("$k: $v");

 204                      //$this->xdebug('ns_prefix: '.$this->getPrefix($k));

 205                      if($ns_prefix = substr(strrchr($k,':'),1)){
 206                          //$this->xdebug("Add namespace[$ns_prefix] = $v");

 207                          $this->namespaces[$ns_prefix] = $v;
 208                      } else {
 209                          $this->defaultNamespace[$pos] = $v;
 210                          if (! $this->getPrefixFromNamespace($v)) {
 211                              $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
 212                          }
 213                      }
 214                      if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
 215                          $this->XMLSchemaVersion = $v;
 216                          $this->namespaces['xsi'] = $v.'-instance';
 217                      }
 218                  }
 219              }
 220              foreach($attrs as $k => $v){
 221                  // expand each attribute

 222                  $k = strpos($k,':') ? $this->expandQname($k) : $k;
 223                  $v = strpos($v,':') ? $this->expandQname($v) : $v;
 224                  $eAttrs[$k] = $v;
 225              }
 226              $attrs = $eAttrs;
 227          } else {
 228              $attrs = array();
 229          }
 230          // find status, register data

 231          switch($name){
 232              case 'all':            // (optional) compositor content for a complexType
 233              case 'choice':
 234              case 'group':
 235              case 'sequence':
 236                  //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");

 237                  $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
 238                  //if($name == 'all' || $name == 'sequence'){

 239                  //    $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';

 240                  //}

 241              break;
 242              case 'attribute':    // complexType attribute
 243                  //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);

 244                  $this->xdebug("parsing attribute:");
 245                  $this->appendDebug($this->varDump($attrs));
 246                  if (!isset($attrs['form'])) {
 247                      $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
 248                  }
 249                  if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
 250                      $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 251                      if (!strpos($v, ':')) {
 252                          // no namespace in arrayType attribute value...

 253                          if ($this->defaultNamespace[$pos]) {
 254                              // ...so use the default

 255                              $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 256                          }
 257                      }
 258                  }
 259                  if(isset($attrs['name'])){
 260                      $this->attributes[$attrs['name']] = $attrs;
 261                      $aname = $attrs['name'];
 262                  } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
 263                      if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
 264                          $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 265                      } else {
 266                          $aname = '';
 267                      }
 268                  } elseif(isset($attrs['ref'])){
 269                      $aname = $attrs['ref'];
 270                      $this->attributes[$attrs['ref']] = $attrs;
 271                  }
 272                  
 273                  if($this->currentComplexType){    // This should *always* be
 274                      $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
 275                  }
 276                  // arrayType attribute

 277                  if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
 278                      $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 279                      $prefix = $this->getPrefix($aname);
 280                      if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
 281                          $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 282                      } else {
 283                          $v = '';
 284                      }
 285                      if(strpos($v,'[,]')){
 286                          $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
 287                      }
 288                      $v = substr($v,0,strpos($v,'[')); // clip the []

 289                      if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
 290                          $v = $this->XMLSchemaVersion.':'.$v;
 291                      }
 292                      $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
 293                  }
 294              break;
 295              case 'complexContent':    // (optional) content for a complexType
 296              break;
 297              case 'complexType':
 298                  array_push($this->complexTypeStack, $this->currentComplexType);
 299                  if(isset($attrs['name'])){
 300                      // TODO: what is the scope of named complexTypes that appear

 301                      //       nested within other c complexTypes?

 302                      $this->xdebug('processing named complexType '.$attrs['name']);
 303                      //$this->currentElement = false;

 304                      $this->currentComplexType = $attrs['name'];
 305                      $this->complexTypes[$this->currentComplexType] = $attrs;
 306                      $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
 307                      // This is for constructs like

 308                      //           <complexType name="ListOfString" base="soap:Array">

 309                      //                <sequence>

 310                      //                    <element name="string" type="xsd:string"

 311                      //                        minOccurs="0" maxOccurs="unbounded" />

 312                      //                </sequence>

 313                      //            </complexType>

 314                      if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
 315                          $this->xdebug('complexType is unusual array');
 316                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 317                      } else {
 318                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
 319                      }
 320                  } else {
 321                      $name = $this->CreateTypeName($this->currentElement);
 322                      $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
 323                      $this->currentComplexType = $name;
 324                      //$this->currentElement = false;

 325                      $this->complexTypes[$this->currentComplexType] = $attrs;
 326                      $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
 327                      // This is for constructs like

 328                      //           <complexType name="ListOfString" base="soap:Array">

 329                      //                <sequence>

 330                      //                    <element name="string" type="xsd:string"

 331                      //                        minOccurs="0" maxOccurs="unbounded" />

 332                      //                </sequence>

 333                      //            </complexType>

 334                      if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
 335                          $this->xdebug('complexType is unusual array');
 336                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 337                      } else {
 338                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
 339                      }
 340                  }
 341              break;
 342              case 'element':
 343                  array_push($this->elementStack, $this->currentElement);
 344                  if (!isset($attrs['form'])) {
 345                      $attrs['form'] = $this->schemaInfo['elementFormDefault'];
 346                  }
 347                  if(isset($attrs['type'])){
 348                      $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
 349                      if (! $this->getPrefix($attrs['type'])) {
 350                          if ($this->defaultNamespace[$pos]) {
 351                              $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
 352                              $this->xdebug('used default namespace to make type ' . $attrs['type']);
 353                          }
 354                      }
 355                      // This is for constructs like

 356                      //           <complexType name="ListOfString" base="soap:Array">

 357                      //                <sequence>

 358                      //                    <element name="string" type="xsd:string"

 359                      //                        minOccurs="0" maxOccurs="unbounded" />

 360                      //                </sequence>

 361                      //            </complexType>

 362                      if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
 363                          $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
 364                          $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
 365                      }
 366                      $this->currentElement = $attrs['name'];
 367                      $ename = $attrs['name'];
 368                  } elseif(isset($attrs['ref'])){
 369                      $this->xdebug("processing element as ref to ".$attrs['ref']);
 370                      $this->currentElement = "ref to ".$attrs['ref'];
 371                      $ename = $this->getLocalPart($attrs['ref']);
 372                  } else {
 373                      $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
 374                      $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
 375                      $this->currentElement = $attrs['name'];
 376                      $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
 377                      $ename = $attrs['name'];
 378                  }
 379                  if (isset($ename) && $this->currentComplexType) {
 380                      $this->xdebug("add element $ename to complexType $this->currentComplexType");
 381                      $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
 382                  } elseif (!isset($attrs['ref'])) {
 383                      $this->xdebug("add element $ename to elements array");
 384                      $this->elements[ $attrs['name'] ] = $attrs;
 385                      $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
 386                  }
 387              break;
 388              case 'enumeration':    //    restriction value list member
 389                  $this->xdebug('enumeration ' . $attrs['value']);
 390                  if ($this->currentSimpleType) {
 391                      $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
 392                  } elseif ($this->currentComplexType) {
 393                      $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
 394                  }
 395              break;
 396              case 'extension':    // simpleContent or complexContent type extension
 397                  $this->xdebug('extension ' . $attrs['base']);
 398                  if ($this->currentComplexType) {
 399                      $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
 400                  }
 401              break;
 402              case 'import':
 403                  if (isset($attrs['schemaLocation'])) {
 404                      //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);

 405                      $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
 406                  } else {
 407                      //$this->xdebug('import namespace ' . $attrs['namespace']);

 408                      $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
 409                      if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
 410                          $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
 411                      }
 412                  }
 413              break;
 414              case 'list':    // simpleType value list
 415              break;
 416              case 'restriction':    // simpleType, simpleContent or complexContent value restriction
 417                  $this->xdebug('restriction ' . $attrs['base']);
 418                  if($this->currentSimpleType){
 419                      $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
 420                  } elseif($this->currentComplexType){
 421                      $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
 422                      if(strstr($attrs['base'],':') == ':Array'){
 423                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 424                      }
 425                  }
 426              break;
 427              case 'schema':
 428                  $this->schemaInfo = $attrs;
 429                  $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
 430                  if (isset($attrs['targetNamespace'])) {
 431                      $this->schemaTargetNamespace = $attrs['targetNamespace'];
 432                  }
 433                  if (!isset($attrs['elementFormDefault'])) {
 434                      $this->schemaInfo['elementFormDefault'] = 'unqualified';
 435                  }
 436                  if (!isset($attrs['attributeFormDefault'])) {
 437                      $this->schemaInfo['attributeFormDefault'] = 'unqualified';
 438                  }
 439              break;
 440              case 'simpleContent':    // (optional) content for a complexType
 441              break;
 442              case 'simpleType':
 443                  array_push($this->simpleTypeStack, $this->currentSimpleType);
 444                  if(isset($attrs['name'])){
 445                      $this->xdebug("processing simpleType for name " . $attrs['name']);
 446                      $this->currentSimpleType = $attrs['name'];
 447                      $this->simpleTypes[ $attrs['name'] ] = $attrs;
 448                      $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
 449                      $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
 450                  } else {
 451                      $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
 452                      $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
 453                      $this->currentSimpleType = $name;
 454                      //$this->currentElement = false;

 455                      $this->simpleTypes[$this->currentSimpleType] = $attrs;
 456                      $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
 457                  }
 458              break;
 459              case 'union':    // simpleType type list
 460              break;
 461              default:
 462                  //$this->xdebug("do not have anything to do for element $name");

 463          }
 464      }
 465  
 466      /**

 467      * end-element handler

 468      *

 469      * @param    string $parser XML parser object

 470      * @param    string $name element name

 471      * @access   private

 472      */
 473  	function schemaEndElement($parser, $name) {
 474          // bring depth down a notch

 475          $this->depth--;
 476          // position of current element is equal to the last value left in depth_array for my depth

 477          if(isset($this->depth_array[$this->depth])){
 478              $pos = $this->depth_array[$this->depth];
 479          }
 480          // get element prefix

 481          if ($prefix = $this->getPrefix($name)){
 482              // get unqualified name

 483              $name = $this->getLocalPart($name);
 484          } else {
 485              $prefix = '';
 486          }
 487          // move on...

 488          if($name == 'complexType'){
 489              $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
 490              $this->currentComplexType = array_pop($this->complexTypeStack);
 491              //$this->currentElement = false;

 492          }
 493          if($name == 'element'){
 494              $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
 495              $this->currentElement = array_pop($this->elementStack);
 496          }
 497          if($name == 'simpleType'){
 498              $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
 499              $this->currentSimpleType = array_pop($this->simpleTypeStack);
 500          }
 501      }
 502  
 503      /**

 504      * element content handler

 505      *

 506      * @param    string $parser XML parser object

 507      * @param    string $data element content

 508      * @access   private

 509      */
 510  	function schemaCharacterData($parser, $data){
 511          $pos = $this->depth_array[$this->depth - 1];
 512          $this->message[$pos]['cdata'] .= $data;
 513      }
 514  
 515      /**

 516      * serialize the schema

 517      *

 518      * @access   public

 519      */
 520  	function serializeSchema(){
 521  
 522          $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
 523          $xml = '';
 524          // imports

 525          if (sizeof($this->imports) > 0) {
 526              foreach($this->imports as $ns => $list) {
 527                  foreach ($list as $ii) {
 528                      if ($ii['location'] != '') {
 529                          $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
 530                      } else {
 531                          $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
 532                      }
 533                  }
 534              } 
 535          } 
 536          // complex types

 537          foreach($this->complexTypes as $typeName => $attrs){
 538              $contentStr = '';
 539              // serialize child elements

 540              if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
 541                  foreach($attrs['elements'] as $element => $eParts){
 542                      if(isset($eParts['ref'])){
 543                          $contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
 544                      } else {
 545                          $contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
 546                          foreach ($eParts as $aName => $aValue) {
 547                              // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable

 548                              if ($aName != 'name' && $aName != 'type') {
 549                                  $contentStr .= " $aName=\"$aValue\"";
 550                              }
 551                          }
 552                          $contentStr .= "/>\n";
 553                      }
 554                  }
 555                  // compositor wraps elements

 556                  if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
 557                      $contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
 558                  }
 559              }
 560              // attributes

 561              if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
 562                  foreach($attrs['attrs'] as $attr => $aParts){
 563                      $contentStr .= "    <$schemaPrefix:attribute";
 564                      foreach ($aParts as $a => $v) {
 565                          if ($a == 'ref' || $a == 'type') {
 566                              $contentStr .= " $a=\"".$this->contractQName($v).'"';
 567                          } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
 568                              $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
 569                              $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
 570                          } else {
 571                              $contentStr .= " $a=\"$v\"";
 572                          }
 573                      }
 574                      $contentStr .= "/>\n";
 575                  }
 576              }
 577              // if restriction

 578              if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
 579                  $contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
 580                  // complex or simple content

 581                  if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
 582                      $contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
 583                  }
 584              }
 585              // finalize complex type

 586              if($contentStr != ''){
 587                  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
 588              } else {
 589                  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
 590              }
 591              $xml .= $contentStr;
 592          }
 593          // simple types

 594          if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
 595              foreach($this->simpleTypes as $typeName => $eParts){
 596                  $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
 597                  if (isset($eParts['enumeration'])) {
 598                      foreach ($eParts['enumeration'] as $e) {
 599                          $xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
 600                      }
 601                  }
 602                  $xml .= "  </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
 603              }
 604          }
 605          // elements

 606          if(isset($this->elements) && count($this->elements) > 0){
 607              foreach($this->elements as $element => $eParts){
 608                  $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
 609              }
 610          }
 611          // attributes

 612          if(isset($this->attributes) && count($this->attributes) > 0){
 613              foreach($this->attributes as $attr => $aParts){
 614                  $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
 615              }
 616          }
 617          // finish 'er up

 618          $attr = '';
 619          foreach ($this->schemaInfo as $k => $v) {
 620              if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
 621                  $attr .= " $k=\"$v\"";
 622              }
 623          }
 624          $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
 625          foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
 626              $el .= " xmlns:$nsp=\"$ns\"";
 627          }
 628          $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
 629          return $xml;
 630      }
 631  
 632      /**

 633      * adds debug data to the clas level debug string

 634      *

 635      * @param    string $string debug data

 636      * @access   private

 637      */
 638  	function xdebug($string){
 639          $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
 640      }
 641  
 642      /**

 643      * get the PHP type of a user defined type in the schema

 644      * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays

 645      * returns false if no type exists, or not w/ the given namespace

 646      * else returns a string that is either a native php type, or 'struct'

 647      *

 648      * @param string $type name of defined type

 649      * @param string $ns namespace of type

 650      * @return mixed

 651      * @access public

 652      * @deprecated

 653      */
 654  	function getPHPType($type,$ns){
 655          if(isset($this->typemap[$ns][$type])){
 656              //print "found type '$type' and ns $ns in typemap<br>";

 657              return $this->typemap[$ns][$type];
 658          } elseif(isset($this->complexTypes[$type])){
 659              //print "getting type '$type' and ns $ns from complexTypes array<br>";

 660              return $this->complexTypes[$type]['phpType'];
 661          }
 662          return false;
 663      }
 664  
 665      /**

 666      * returns an associative array of information about a given type

 667      * returns false if no type exists by the given name

 668      *

 669      *    For a complexType typeDef = array(

 670      *    'restrictionBase' => '',

 671      *    'phpType' => '',

 672      *    'compositor' => '(sequence|all)',

 673      *    'elements' => array(), // refs to elements array

 674      *    'attrs' => array() // refs to attributes array

 675      *    ... and so on (see addComplexType)

 676      *    )

 677      *

 678      *   For simpleType or element, the array has different keys.

 679      *

 680      * @param string $type

 681      * @return mixed

 682      * @access public

 683      * @see addComplexType

 684      * @see addSimpleType

 685      * @see addElement

 686      */
 687  	function getTypeDef($type){
 688          //$this->debug("in getTypeDef for type $type");

 689          if (substr($type, -1) == '^') {
 690              $is_element = 1;
 691              $type = substr($type, 0, -1);
 692          } else {
 693              $is_element = 0;
 694          }
 695  
 696          if((! $is_element) && isset($this->complexTypes[$type])){
 697              $this->xdebug("in getTypeDef, found complexType $type");
 698              return $this->complexTypes[$type];
 699          } elseif((! $is_element) && isset($this->simpleTypes[$type])){
 700              $this->xdebug("in getTypeDef, found simpleType $type");
 701              if (!isset($this->simpleTypes[$type]['phpType'])) {
 702                  // get info for type to tack onto the simple type

 703                  // TODO: can this ever really apply (i.e. what is a simpleType really?)

 704                  $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
 705                  $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
 706                  $etype = $this->getTypeDef($uqType);
 707                  if ($etype) {
 708                      $this->xdebug("in getTypeDef, found type for simpleType $type:");
 709                      $this->xdebug($this->varDump($etype));
 710                      if (isset($etype['phpType'])) {
 711                          $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
 712                      }
 713                      if (isset($etype['elements'])) {
 714                          $this->simpleTypes[$type]['elements'] = $etype['elements'];
 715                      }
 716                  }
 717              }
 718              return $this->simpleTypes[$type];
 719          } elseif(isset($this->elements[$type])){
 720              $this->xdebug("in getTypeDef, found element $type");
 721              if (!isset($this->elements[$type]['phpType'])) {
 722                  // get info for type to tack onto the element

 723                  $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
 724                  $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
 725                  $etype = $this->getTypeDef($uqType);
 726                  if ($etype) {
 727                      $this->xdebug("in getTypeDef, found type for element $type:");
 728                      $this->xdebug($this->varDump($etype));
 729                      if (isset($etype['phpType'])) {
 730                          $this->elements[$type]['phpType'] = $etype['phpType'];
 731                      }
 732                      if (isset($etype['elements'])) {
 733                          $this->elements[$type]['elements'] = $etype['elements'];
 734                      }
 735                  } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
 736                      $this->xdebug("in getTypeDef, element $type is an XSD type");
 737                      $this->elements[$type]['phpType'] = 'scalar';
 738                  }
 739              }
 740              return $this->elements[$type];
 741          } elseif(isset($this->attributes[$type])){
 742              $this->xdebug("in getTypeDef, found attribute $type");
 743              return $this->attributes[$type];
 744          } elseif (ereg('_ContainedType$', $type)) {
 745              $this->xdebug("in getTypeDef, have an untyped element $type");
 746              $typeDef['typeClass'] = 'simpleType';
 747              $typeDef['phpType'] = 'scalar';
 748              $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
 749              return $typeDef;
 750          }
 751          $this->xdebug("in getTypeDef, did not find $type");
 752          return false;
 753      }
 754  
 755      /**

 756      * returns a sample serialization of a given type, or false if no type by the given name

 757      *

 758      * @param string $type name of type

 759      * @return mixed

 760      * @access public

 761      * @deprecated

 762      */
 763      function serializeTypeDef($type){
 764          //print "in sTD() for type $type<br>";

 765      if($typeDef = $this->getTypeDef($type)){
 766          $str .= '<'.$type;
 767          if(is_array($typeDef['attrs'])){
 768          foreach($typeDef['attrs'] as $attName => $data){
 769              $str .= " $attName=\"{type = ".$data['type']."}\"";
 770          }
 771          }
 772          $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
 773          if(count($typeDef['elements']) > 0){
 774          $str .= ">";
 775          foreach($typeDef['elements'] as $element => $eData){
 776              $str .= $this->serializeTypeDef($element);
 777          }
 778          $str .= "</$type>";
 779          } elseif($typeDef['typeClass'] == 'element') {
 780          $str .= "></$type>";
 781          } else {
 782          $str .= "/>";
 783          }
 784              return $str;
 785      }
 786          return false;
 787      }
 788  
 789      /**

 790      * returns HTML form elements that allow a user

 791      * to enter values for creating an instance of the given type.

 792      *

 793      * @param string $name name for type instance

 794      * @param string $type name of type

 795      * @return string

 796      * @access public

 797      * @deprecated

 798      */
 799  	function typeToForm($name,$type){
 800          // get typedef

 801          if($typeDef = $this->getTypeDef($type)){
 802              // if struct

 803              if($typeDef['phpType'] == 'struct'){
 804                  $buffer .= '<table>';
 805                  foreach($typeDef['elements'] as $child => $childDef){
 806                      $buffer .= "
 807                      <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
 808                      <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
 809                  }
 810                  $buffer .= '</table>';
 811              // if array

 812              } elseif($typeDef['phpType'] == 'array'){
 813                  $buffer .= '<table>';
 814                  for($i=0;$i < 3; $i++){
 815                      $buffer .= "
 816                      <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
 817                      <td><input type='text' name='parameters[".$name."][]'></td></tr>";
 818                  }
 819                  $buffer .= '</table>';
 820              // if scalar

 821              } else {
 822                  $buffer .= "<input type='text' name='parameters[$name]'>";
 823              }
 824          } else {
 825              $buffer .= "<input type='text' name='parameters[$name]'>";
 826          }
 827          return $buffer;
 828      }
 829      
 830      /**

 831      * adds a complex type to the schema

 832      * 

 833      * example: array

 834      * 

 835      * addType(

 836      *     'ArrayOfstring',

 837      *     'complexType',

 838      *     'array',

 839      *     '',

 840      *     'SOAP-ENC:Array',

 841      *     array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),

 842      *     'xsd:string'

 843      * );

 844      * 

 845      * example: PHP associative array ( SOAP Struct )

 846      * 

 847      * addType(

 848      *     'SOAPStruct',

 849      *     'complexType',

 850      *     'struct',

 851      *     'all',

 852      *     array('myVar'=> array('name'=>'myVar','type'=>'string')

 853      * );

 854      * 

 855      * @param name

 856      * @param typeClass (complexType|simpleType|attribute)

 857      * @param phpType: currently supported are array and struct (php assoc array)

 858      * @param compositor (all|sequence|choice)

 859      * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)

 860      * @param elements = array ( name = array(name=>'',type=>'') )

 861      * @param attrs = array(

 862      *     array(

 863      *        'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",

 864      *        "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"

 865      *     )

 866      * )

 867      * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)

 868      * @access public

 869      * @see getTypeDef

 870      */
 871  	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
 872          $this->complexTypes[$name] = array(
 873          'name'        => $name,
 874          'typeClass'    => $typeClass,
 875          'phpType'    => $phpType,
 876          'compositor'=> $compositor,
 877          'restrictionBase' => $restrictionBase,
 878          'elements'    => $elements,
 879          'attrs'        => $attrs,
 880          'arrayType'    => $arrayType
 881          );
 882          
 883          $this->xdebug("addComplexType $name:");
 884          $this->appendDebug($this->varDump($this->complexTypes[$name]));
 885      }
 886      
 887      /**

 888      * adds a simple type to the schema

 889      *

 890      * @param string $name

 891      * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)

 892      * @param string $typeClass (should always be simpleType)

 893      * @param string $phpType (should always be scalar)

 894      * @param array $enumeration array of values

 895      * @access public

 896      * @see nusoap_xmlschema

 897      * @see getTypeDef

 898      */
 899  	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
 900          $this->simpleTypes[$name] = array(
 901          'name'            => $name,
 902          'typeClass'        => $typeClass,
 903          'phpType'        => $phpType,
 904          'type'            => $restrictionBase,
 905          'enumeration'    => $enumeration
 906          );
 907          
 908          $this->xdebug("addSimpleType $name:");
 909          $this->appendDebug($this->varDump($this->simpleTypes[$name]));
 910      }
 911  
 912      /**

 913      * adds an element to the schema

 914      *

 915      * @param array $attrs attributes that must include name and type

 916      * @see nusoap_xmlschema

 917      * @access public

 918      */
 919  	function addElement($attrs) {
 920          if (! $this->getPrefix($attrs['type'])) {
 921              $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
 922          }
 923          $this->elements[ $attrs['name'] ] = $attrs;
 924          $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
 925          
 926          $this->xdebug("addElement " . $attrs['name']);
 927          $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
 928      }
 929  }
 930  
 931  /**

 932   * Backward compatibility

 933   */
 934  class XMLSchema extends nusoap_xmlschema {
 935  }
 936  
 937  
 938  ?>


Généré le : Thu Nov 29 09:42:17 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics