[ Index ]
 

Code source de CMS made simple 1.0.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/modules/nuSOAP/classes/ -> 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  * no validation... yet.

   9  * very experimental and limited. As is discussed on XML-DEV, I'm one of the people

  10  * that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty

  11  * tutorials I refer to :)

  12  *

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

  14  * @version  $Id: class.xmlschema.php,v 1.39 2005/08/04 01:27:42 snichol Exp $

  15  * @access   public

  16  */
  17  class XMLSchema extends nusoap_base  {
  18      
  19      // files

  20      var $schema = '';
  21      var $xml = '';
  22      // namespaces

  23      var $enclosingNamespaces;
  24      // schema info

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

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

  39      var $imports = array();
  40      // parser vars

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

  49      * constructor

  50      *

  51      * @param    string $schema schema document URI

  52      * @param    string $xml xml document URI

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

  54      * @access   public

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

  60          $this->schema = $schema;
  61          $this->xml = $xml;
  62  
  63          // namespaces

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

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

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

  82      * parse an XML file

  83      *

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

  85      * @param string $type, (schema | xml)

  86      * @return boolean

  87      * @access public

  88      */
  89  	function parseFile($xml,$type){
  90          // parse xml file

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

 109      * parse an XML string

 110      *

 111      * @param    string $xml path or URL

 112      * @param string $type, (schema|xml)

 113      * @access   private

 114      */
 115  	function parseString($xml,$type){
 116          // parse xml string

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

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

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

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

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

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

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

 156      * start-element handler

 157      *

 158      * @param    string $parser XML parser object

 159      * @param    string $name element name

 160      * @param    string $attrs associative array of attributes

 161      * @access   private

 162      */
 163  	function schemaStartElement($parser, $name, $attrs) {
 164          
 165          // position in the total number of elements, starting from 0

 166          $pos = $this->position++;
 167          $depth = $this->depth++;
 168          // set self as current value for this depth

 169          $this->depth_array[$depth] = $pos;
 170          $this->message[$pos] = array('cdata' => ''); 
 171          if ($depth > 0) {
 172              $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
 173          } else {
 174              $this->defaultNamespace[$pos] = false;
 175          }
 176  
 177          // get element prefix

 178          if($prefix = $this->getPrefix($name)){
 179              // get unqualified name

 180              $name = $this->getLocalPart($name);
 181          } else {
 182              $prefix = '';
 183          }
 184          
 185          // loop thru attributes, expanding, and registering namespace declarations

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

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

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

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

 194                          $this->namespaces[$ns_prefix] = $v;
 195                      } else {
 196                          $this->defaultNamespace[$pos] = $v;
 197                          if (! $this->getPrefixFromNamespace($v)) {
 198                              $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
 199                          }
 200                      }
 201                      if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
 202                          $this->XMLSchemaVersion = $v;
 203                          $this->namespaces['xsi'] = $v.'-instance';
 204                      }
 205                  }
 206              }
 207              foreach($attrs as $k => $v){
 208                  // expand each attribute

 209                  $k = strpos($k,':') ? $this->expandQname($k) : $k;
 210                  $v = strpos($v,':') ? $this->expandQname($v) : $v;
 211                  $eAttrs[$k] = $v;
 212              }
 213              $attrs = $eAttrs;
 214          } else {
 215              $attrs = array();
 216          }
 217          // find status, register data

 218          switch($name){
 219              case 'all':            // (optional) compositor content for a complexType
 220              case 'choice':
 221              case 'group':
 222              case 'sequence':
 223                  //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");

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

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

 227                  //}

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

 231                  $this->xdebug("parsing attribute:");
 232                  $this->appendDebug($this->varDump($attrs));
 233                  if (!isset($attrs['form'])) {
 234                      $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
 235                  }
 236                  if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
 237                      $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 238                      if (!strpos($v, ':')) {
 239                          // no namespace in arrayType attribute value...

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

 242                              $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 243                          }
 244                      }
 245                  }
 246                  if(isset($attrs['name'])){
 247                      $this->attributes[$attrs['name']] = $attrs;
 248                      $aname = $attrs['name'];
 249                  } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
 250                      if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
 251                          $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 252                      } else {
 253                          $aname = '';
 254                      }
 255                  } elseif(isset($attrs['ref'])){
 256                      $aname = $attrs['ref'];
 257                      $this->attributes[$attrs['ref']] = $attrs;
 258                  }
 259                  
 260                  if($this->currentComplexType){    // This should *always* be
 261                      $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
 262                  }
 263                  // arrayType attribute

 264                  if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
 265                      $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 266                      $prefix = $this->getPrefix($aname);
 267                      if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
 268                          $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
 269                      } else {
 270                          $v = '';
 271                      }
 272                      if(strpos($v,'[,]')){
 273                          $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
 274                      }
 275                      $v = substr($v,0,strpos($v,'[')); // clip the []

 276                      if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
 277                          $v = $this->XMLSchemaVersion.':'.$v;
 278                      }
 279                      $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
 280                  }
 281              break;
 282              case 'complexContent':    // (optional) content for a complexType
 283              break;
 284              case 'complexType':
 285                  $this->complexTypeStack[] = $this->currentComplexType;
 286                  if(isset($attrs['name'])){
 287                      $this->xdebug('processing named complexType '.$attrs['name']);
 288                      //$this->currentElement = false;

 289                      $this->currentComplexType = $attrs['name'];
 290                      $this->complexTypes[$this->currentComplexType] = $attrs;
 291                      $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
 292                      // This is for constructs like

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

 294                      //                <sequence>

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

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

 297                      //                </sequence>

 298                      //            </complexType>

 299                      if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
 300                          $this->xdebug('complexType is unusual array');
 301                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 302                      } else {
 303                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
 304                      }
 305                  }else{
 306                      $this->xdebug('processing unnamed complexType for element '.$this->currentElement);
 307                      $this->currentComplexType = $this->currentElement . '_ContainedType';
 308                      //$this->currentElement = false;

 309                      $this->complexTypes[$this->currentComplexType] = $attrs;
 310                      $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
 311                      // This is for constructs like

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

 313                      //                <sequence>

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

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

 316                      //                </sequence>

 317                      //            </complexType>

 318                      if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
 319                          $this->xdebug('complexType is unusual array');
 320                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 321                      } else {
 322                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
 323                      }
 324                  }
 325              break;
 326              case 'element':
 327                  $this->elementStack[] = $this->currentElement;
 328                  // elements defined as part of a complex type should

 329                  // not really be added to $this->elements, but for some

 330                  // reason, they are

 331                  if (!isset($attrs['form'])) {
 332                      $attrs['form'] = $this->schemaInfo['elementFormDefault'];
 333                  }
 334                  if(isset($attrs['type'])){
 335                      $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
 336                      if (! $this->getPrefix($attrs['type'])) {
 337                          if ($this->defaultNamespace[$pos]) {
 338                              $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
 339                              $this->xdebug('used default namespace to make type ' . $attrs['type']);
 340                          }
 341                      }
 342                      // This is for constructs like

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

 344                      //                <sequence>

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

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

 347                      //                </sequence>

 348                      //            </complexType>

 349                      if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
 350                          $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
 351                          $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
 352                      }
 353                      $this->currentElement = $attrs['name'];
 354                      $this->elements[ $attrs['name'] ] = $attrs;
 355                      $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
 356                      $ename = $attrs['name'];
 357                  } elseif(isset($attrs['ref'])){
 358                      $this->xdebug("processing element as ref to ".$attrs['ref']);
 359                      $this->currentElement = "ref to ".$attrs['ref'];
 360                      $ename = $this->getLocalPart($attrs['ref']);
 361                  } else {
 362                      $this->xdebug("processing untyped element ".$attrs['name']);
 363                      $this->currentElement = $attrs['name'];
 364                      $this->elements[ $attrs['name'] ] = $attrs;
 365                      $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
 366                      $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
 367                      $this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
 368                      $ename = $attrs['name'];
 369                  }
 370                  if(isset($ename) && $this->currentComplexType){
 371                      $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
 372                  }
 373              break;
 374              case 'enumeration':    //    restriction value list member
 375                  $this->xdebug('enumeration ' . $attrs['value']);
 376                  if ($this->currentSimpleType) {
 377                      $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
 378                  } elseif ($this->currentComplexType) {
 379                      $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
 380                  }
 381              break;
 382              case 'extension':    // simpleContent or complexContent type extension
 383                  $this->xdebug('extension ' . $attrs['base']);
 384                  if ($this->currentComplexType) {
 385                      $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
 386                  }
 387              break;
 388              case 'import':
 389                  if (isset($attrs['schemaLocation'])) {
 390                      //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);

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

 394                      $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
 395                      if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
 396                          $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
 397                      }
 398                  }
 399              break;
 400              case 'list':    // simpleType value list
 401              break;
 402              case 'restriction':    // simpleType, simpleContent or complexContent value restriction
 403                  $this->xdebug('restriction ' . $attrs['base']);
 404                  if($this->currentSimpleType){
 405                      $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
 406                  } elseif($this->currentComplexType){
 407                      $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
 408                      if(strstr($attrs['base'],':') == ':Array'){
 409                          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
 410                      }
 411                  }
 412              break;
 413              case 'schema':
 414                  $this->schemaInfo = $attrs;
 415                  $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
 416                  if (isset($attrs['targetNamespace'])) {
 417                      $this->schemaTargetNamespace = $attrs['targetNamespace'];
 418                  }
 419                  if (!isset($attrs['elementFormDefault'])) {
 420                      $this->schemaInfo['elementFormDefault'] = 'unqualified';
 421                  }
 422                  if (!isset($attrs['attributeFormDefault'])) {
 423                      $this->schemaInfo['attributeFormDefault'] = 'unqualified';
 424                  }
 425              break;
 426              case 'simpleContent':    // (optional) content for a complexType
 427              break;
 428              case 'simpleType':
 429                  $this->simpleTypeStack[] = $this->currentSimpleType;
 430                  if(isset($attrs['name'])){
 431                      $this->xdebug("processing simpleType for name " . $attrs['name']);
 432                      $this->currentSimpleType = $attrs['name'];
 433                      $this->simpleTypes[ $attrs['name'] ] = $attrs;
 434                      $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
 435                      $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
 436                  } else {
 437                      $this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
 438                      $this->currentSimpleType = $this->currentElement . '_ContainedType';
 439                      //$this->currentElement = false;

 440                      $this->simpleTypes[$this->currentSimpleType] = $attrs;
 441                      $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
 442                  }
 443              break;
 444              case 'union':    // simpleType type list
 445              break;
 446              default:
 447                  //$this->xdebug("do not have anything to do for element $name");

 448          }
 449      }
 450  
 451      /**

 452      * end-element handler

 453      *

 454      * @param    string $parser XML parser object

 455      * @param    string $name element name

 456      * @access   private

 457      */
 458  	function schemaEndElement($parser, $name) {
 459          // bring depth down a notch

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

 462          if(isset($this->depth_array[$this->depth])){
 463              $pos = $this->depth_array[$this->depth];
 464          }
 465          // get element prefix

 466          if ($prefix = $this->getPrefix($name)){
 467              // get unqualified name

 468              $name = $this->getLocalPart($name);
 469          } else {
 470              $prefix = '';
 471          }
 472          // move on...

 473          if($name == 'complexType'){
 474              $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
 475              $this->currentComplexType = array_pop($this->complexTypeStack);
 476              //$this->currentElement = false;

 477          }
 478          if($name == 'element'){
 479              $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
 480              $this->currentElement = array_pop($this->elementStack);
 481          }
 482          if($name == 'simpleType'){
 483              $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
 484              $this->currentSimpleType = array_pop($this->simpleTypeStack);
 485          }
 486      }
 487  
 488      /**

 489      * element content handler

 490      *

 491      * @param    string $parser XML parser object

 492      * @param    string $data element content

 493      * @access   private

 494      */
 495  	function schemaCharacterData($parser, $data){
 496          $pos = $this->depth_array[$this->depth - 1];
 497          $this->message[$pos]['cdata'] .= $data;
 498      }
 499  
 500      /**

 501      * serialize the schema

 502      *

 503      * @access   public

 504      */
 505  	function serializeSchema(){
 506  
 507          $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
 508          $xml = '';
 509          // imports

 510          if (sizeof($this->imports) > 0) {
 511              foreach($this->imports as $ns => $list) {
 512                  foreach ($list as $ii) {
 513                      if ($ii['location'] != '') {
 514                          $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
 515                      } else {
 516                          $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
 517                      }
 518                  }
 519              } 
 520          } 
 521          // complex types

 522          foreach($this->complexTypes as $typeName => $attrs){
 523              $contentStr = '';
 524              // serialize child elements

 525              if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
 526                  foreach($attrs['elements'] as $element => $eParts){
 527                      if(isset($eParts['ref'])){
 528                          $contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
 529                      } else {
 530                          $contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
 531                          foreach ($eParts as $aName => $aValue) {
 532                              // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable

 533                              if ($aName != 'name' && $aName != 'type') {
 534                                  $contentStr .= " $aName=\"$aValue\"";
 535                              }
 536                          }
 537                          $contentStr .= "/>\n";
 538                      }
 539                  }
 540                  // compositor wraps elements

 541                  if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
 542                      $contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
 543                  }
 544              }
 545              // attributes

 546              if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
 547                  foreach($attrs['attrs'] as $attr => $aParts){
 548                      $contentStr .= "    <$schemaPrefix:attribute";
 549                      foreach ($aParts as $a => $v) {
 550                          if ($a == 'ref' || $a == 'type') {
 551                              $contentStr .= " $a=\"".$this->contractQName($v).'"';
 552                          } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
 553                              $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
 554                              $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
 555                          } else {
 556                              $contentStr .= " $a=\"$v\"";
 557                          }
 558                      }
 559                      $contentStr .= "/>\n";
 560                  }
 561              }
 562              // if restriction

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

 566                  if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
 567                      $contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
 568                  }
 569              }
 570              // finalize complex type

 571              if($contentStr != ''){
 572                  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
 573              } else {
 574                  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
 575              }
 576              $xml .= $contentStr;
 577          }
 578          // simple types

 579          if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
 580              foreach($this->simpleTypes as $typeName => $eParts){
 581                  $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
 582                  if (isset($eParts['enumeration'])) {
 583                      foreach ($eParts['enumeration'] as $e) {
 584                          $xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
 585                      }
 586                  }
 587                  $xml .= " </$schemaPrefix:simpleType>";
 588              }
 589          }
 590          // elements

 591          if(isset($this->elements) && count($this->elements) > 0){
 592              foreach($this->elements as $element => $eParts){
 593                  $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
 594              }
 595          }
 596          // attributes

 597          if(isset($this->attributes) && count($this->attributes) > 0){
 598              foreach($this->attributes as $attr => $aParts){
 599                  $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
 600              }
 601          }
 602          // finish 'er up

 603          $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
 604          foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
 605              $el .= " xmlns:$nsp=\"$ns\"\n";
 606          }
 607          $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
 608          return $xml;
 609      }
 610  
 611      /**

 612      * adds debug data to the clas level debug string

 613      *

 614      * @param    string $string debug data

 615      * @access   private

 616      */
 617  	function xdebug($string){
 618          $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
 619      }
 620  
 621      /**

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

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

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

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

 626      *

 627      * @param string $type, name of defined type

 628      * @param string $ns, namespace of type

 629      * @return mixed

 630      * @access public

 631      * @deprecated

 632      */
 633  	function getPHPType($type,$ns){
 634          if(isset($this->typemap[$ns][$type])){
 635              //print "found type '$type' and ns $ns in typemap<br>";

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

 639              return $this->complexTypes[$type]['phpType'];
 640          }
 641          return false;
 642      }
 643  
 644      /**

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

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

 647      *

 648      *    For a complexType typeDef = array(

 649      *    'restrictionBase' => '',

 650      *    'phpType' => '',

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

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

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

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

 655      *    )

 656      *

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

 658      *

 659      * @param string

 660      * @return mixed

 661      * @access public

 662      * @see addComplexType

 663      * @see addSimpleType

 664      * @see addElement

 665      */
 666  	function getTypeDef($type){
 667          //$this->debug("in getTypeDef for type $type");

 668          if(isset($this->complexTypes[$type])){
 669              $this->xdebug("in getTypeDef, found complexType $type");
 670              return $this->complexTypes[$type];
 671          } elseif(isset($this->simpleTypes[$type])){
 672              $this->xdebug("in getTypeDef, found simpleType $type");
 673              if (!isset($this->simpleTypes[$type]['phpType'])) {
 674                  // get info for type to tack onto the simple type

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

 676                  $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
 677                  $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
 678                  $etype = $this->getTypeDef($uqType);
 679                  if ($etype) {
 680                      $this->xdebug("in getTypeDef, found type for simpleType $type:");
 681                      $this->xdebug($this->varDump($etype));
 682                      if (isset($etype['phpType'])) {
 683                          $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
 684                      }
 685                      if (isset($etype['elements'])) {
 686                          $this->simpleTypes[$type]['elements'] = $etype['elements'];
 687                      }
 688                  }
 689              }
 690              return $this->simpleTypes[$type];
 691          } elseif(isset($this->elements[$type])){
 692              $this->xdebug("in getTypeDef, found element $type");
 693              if (!isset($this->elements[$type]['phpType'])) {
 694                  // get info for type to tack onto the element

 695                  $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
 696                  $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
 697                  $etype = $this->getTypeDef($uqType);
 698                  if ($etype) {
 699                      $this->xdebug("in getTypeDef, found type for element $type:");
 700                      $this->xdebug($this->varDump($etype));
 701                      if (isset($etype['phpType'])) {
 702                          $this->elements[$type]['phpType'] = $etype['phpType'];
 703                      }
 704                      if (isset($etype['elements'])) {
 705                          $this->elements[$type]['elements'] = $etype['elements'];
 706                      }
 707                  } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
 708                      $this->xdebug("in getTypeDef, element $type is an XSD type");
 709                      $this->elements[$type]['phpType'] = 'scalar';
 710                  }
 711              }
 712              return $this->elements[$type];
 713          } elseif(isset($this->attributes[$type])){
 714              $this->xdebug("in getTypeDef, found attribute $type");
 715              return $this->attributes[$type];
 716          } elseif (ereg('_ContainedType$', $type)) {
 717              $this->xdebug("in getTypeDef, have an untyped element $type");
 718              $typeDef['typeClass'] = 'simpleType';
 719              $typeDef['phpType'] = 'scalar';
 720              $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
 721              return $typeDef;
 722          }
 723          $this->xdebug("in getTypeDef, did not find $type");
 724          return false;
 725      }
 726  
 727      /**

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

 729      *

 730      * @param string $type, name of type

 731      * @return mixed

 732      * @access public

 733      * @deprecated

 734      */
 735      function serializeTypeDef($type){
 736          //print "in sTD() for type $type<br>";

 737      if($typeDef = $this->getTypeDef($type)){
 738          $str .= '<'.$type;
 739          if(is_array($typeDef['attrs'])){
 740          foreach($attrs as $attName => $data){
 741              $str .= " $attName=\"{type = ".$data['type']."}\"";
 742          }
 743          }
 744          $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
 745          if(count($typeDef['elements']) > 0){
 746          $str .= ">";
 747          foreach($typeDef['elements'] as $element => $eData){
 748              $str .= $this->serializeTypeDef($element);
 749          }
 750          $str .= "</$type>";
 751          } elseif($typeDef['typeClass'] == 'element') {
 752          $str .= "></$type>";
 753          } else {
 754          $str .= "/>";
 755          }
 756              return $str;
 757      }
 758          return false;
 759      }
 760  
 761      /**

 762      * returns HTML form elements that allow a user

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

 764      *

 765      * @param string $name, name for type instance

 766      * @param string $type, name of type

 767      * @return string

 768      * @access public

 769      * @deprecated

 770      */
 771  	function typeToForm($name,$type){
 772          // get typedef

 773          if($typeDef = $this->getTypeDef($type)){
 774              // if struct

 775              if($typeDef['phpType'] == 'struct'){
 776                  $buffer .= '<table>';
 777                  foreach($typeDef['elements'] as $child => $childDef){
 778                      $buffer .= "
 779                      <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
 780                      <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
 781                  }
 782                  $buffer .= '</table>';
 783              // if array

 784              } elseif($typeDef['phpType'] == 'array'){
 785                  $buffer .= '<table>';
 786                  for($i=0;$i < 3; $i++){
 787                      $buffer .= "
 788                      <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
 789                      <td><input type='text' name='parameters[".$name."][]'></td></tr>";
 790                  }
 791                  $buffer .= '</table>';
 792              // if scalar

 793              } else {
 794                  $buffer .= "<input type='text' name='parameters[$name]'>";
 795              }
 796          } else {
 797              $buffer .= "<input type='text' name='parameters[$name]'>";
 798          }
 799          return $buffer;
 800      }
 801      
 802      /**

 803      * adds a complex type to the schema

 804      * 

 805      * example: array

 806      * 

 807      * addType(

 808      *     'ArrayOfstring',

 809      *     'complexType',

 810      *     'array',

 811      *     '',

 812      *     'SOAP-ENC:Array',

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

 814      *     'xsd:string'

 815      * );

 816      * 

 817      * example: PHP associative array ( SOAP Struct )

 818      * 

 819      * addType(

 820      *     'SOAPStruct',

 821      *     'complexType',

 822      *     'struct',

 823      *     'all',

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

 825      * );

 826      * 

 827      * @param name

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

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

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

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

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

 833      * @param attrs = array(

 834      *     array(

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

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

 837      *     )

 838      * )

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

 840      * @access public

 841      * @see getTypeDef

 842      */
 843  	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
 844          $this->complexTypes[$name] = array(
 845          'name'        => $name,
 846          'typeClass'    => $typeClass,
 847          'phpType'    => $phpType,
 848          'compositor'=> $compositor,
 849          'restrictionBase' => $restrictionBase,
 850          'elements'    => $elements,
 851          'attrs'        => $attrs,
 852          'arrayType'    => $arrayType
 853          );
 854          
 855          $this->xdebug("addComplexType $name:");
 856          $this->appendDebug($this->varDump($this->complexTypes[$name]));
 857      }
 858      
 859      /**

 860      * adds a simple type to the schema

 861      *

 862      * @param string $name

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

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

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

 866      * @param array $enumeration array of values

 867      * @access public

 868      * @see xmlschema

 869      * @see getTypeDef

 870      */
 871  	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
 872          $this->simpleTypes[$name] = array(
 873          'name'            => $name,
 874          'typeClass'        => $typeClass,
 875          'phpType'        => $phpType,
 876          'type'            => $restrictionBase,
 877          'enumeration'    => $enumeration
 878          );
 879          
 880          $this->xdebug("addSimpleType $name:");
 881          $this->appendDebug($this->varDump($this->simpleTypes[$name]));
 882      }
 883  
 884      /**

 885      * adds an element to the schema

 886      *

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

 888      * @see xmlschema

 889      * @access public

 890      */
 891  	function addElement($attrs) {
 892          if (! $this->getPrefix($attrs['type'])) {
 893              $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
 894          }
 895          $this->elements[ $attrs['name'] ] = $attrs;
 896          $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
 897          
 898          $this->xdebug("addElement " . $attrs['name']);
 899          $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
 900      }
 901  }
 902  
 903  
 904  
 905  
 906  ?>


Généré le : Tue Apr 3 18:50:37 2007 par Balluche grâce à PHPXref 0.7