• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

webservice/soap/lib/class.xmlschema.php

Go to the documentation of this file.
00001 <?php
00002 
00003 
00004 
00005 
00017 class XMLSchema extends nusoap_base  {
00018         
00019         // files
00020         var $schema = '';
00021         var $xml = '';
00022         // namespaces
00023         var $enclosingNamespaces;
00024         // schema info
00025         var $schemaInfo = array();
00026         var $schemaTargetNamespace = '';
00027         // types, elements, attributes defined by the schema
00028         var $attributes = array();
00029         var $complexTypes = array();
00030         var $complexTypeStack = array();
00031         var $currentComplexType = null;
00032         var $elements = array();
00033         var $elementStack = array();
00034         var $currentElement = null;
00035         var $simpleTypes = array();
00036         var $simpleTypeStack = array();
00037         var $currentSimpleType = null;
00038         // imports
00039         var $imports = array();
00040         // parser vars
00041         var $parser;
00042         var $position = 0;
00043         var $depth = 0;
00044         var $depth_array = array();
00045         var $message = array();
00046         var $defaultNamespace = array();
00047     
00056         function XMLSchema($schema='',$xml='',$namespaces=array()){
00057                 parent::nusoap_base();
00058                 $this->debug('xmlschema class instantiated, inside constructor');
00059                 // files
00060                 $this->schema = $schema;
00061                 $this->xml = $xml;
00062 
00063                 // namespaces
00064                 $this->enclosingNamespaces = $namespaces;
00065                 $this->namespaces = array_merge($this->namespaces, $namespaces);
00066 
00067                 // parse schema file
00068                 if($schema != ''){
00069                         $this->debug('initial schema file: '.$schema);
00070                         $this->parseFile($schema, 'schema');
00071                 }
00072 
00073                 // parse xml file
00074                 if($xml != ''){
00075                         $this->debug('initial xml file: '.$xml);
00076                         $this->parseFile($xml, 'xml');
00077                 }
00078 
00079         }
00080 
00089         function parseFile($xml,$type){
00090                 // parse xml file
00091                 if($xml != ""){
00092                         $xmlStr = @join("",@file($xml));
00093                         if($xmlStr == ""){
00094                                 $msg = 'Error reading XML from '.$xml;
00095                                 $this->setError($msg);
00096                                 $this->debug($msg);
00097                         return false;
00098                         } else {
00099                                 $this->debug("parsing $xml");
00100                                 $this->parseString($xmlStr,$type);
00101                                 $this->debug("done parsing $xml");
00102                         return true;
00103                         }
00104                 }
00105                 return false;
00106         }
00107 
00115         function parseString($xml,$type){
00116                 // parse xml string
00117                 if($xml != ""){
00118 
00119                 // Create an XML parser.
00120                 $this->parser = xml_parser_create();
00121                 // Set the options for parsing the XML data.
00122                 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
00123 
00124                 // Set the object for the parser.
00125                 xml_set_object($this->parser, $this);
00126 
00127                 // Set the element handlers for the parser.
00128                         if($type == "schema"){
00129                         xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
00130                         xml_set_character_data_handler($this->parser,'schemaCharacterData');
00131                         } elseif($type == "xml"){
00132                                 xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
00133                         xml_set_character_data_handler($this->parser,'xmlCharacterData');
00134                         }
00135 
00136                     // Parse the XML file.
00137                     if(!xml_parse($this->parser,$xml,true)){
00138                         // Display an error message.
00139                                 $errstr = sprintf('XML error parsing XML schema on line %d: %s',
00140                                 xml_get_current_line_number($this->parser),
00141                                 xml_error_string(xml_get_error_code($this->parser))
00142                                 );
00143                                 $this->debug($errstr);
00144                                 $this->debug("XML payload:\n" . $xml);
00145                                 $this->setError($errstr);
00146                 }
00147             
00148                         xml_parser_free($this->parser);
00149                 } else{
00150                         $this->debug('no xml passed to parseString()!!');
00151                         $this->setError('no xml passed to parseString()!!');
00152                 }
00153         }
00154 
00163         function schemaStartElement($parser, $name, $attrs) {
00164                 
00165                 // position in the total number of elements, starting from 0
00166                 $pos = $this->position++;
00167                 $depth = $this->depth++;
00168                 // set self as current value for this depth
00169                 $this->depth_array[$depth] = $pos;
00170                 $this->message[$pos] = array('cdata' => ''); 
00171                 if ($depth > 0) {
00172                         $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
00173                 } else {
00174                         $this->defaultNamespace[$pos] = false;
00175                 }
00176 
00177                 // get element prefix
00178                 if($prefix = $this->getPrefix($name)){
00179                         // get unqualified name
00180                         $name = $this->getLocalPart($name);
00181                 } else {
00182                 $prefix = '';
00183         }
00184                 
00185         // loop thru attributes, expanding, and registering namespace declarations
00186         if(count($attrs) > 0){
00187                 foreach($attrs as $k => $v){
00188                 // if ns declarations, add to class level array of valid namespaces
00189                                 if(ereg("^xmlns",$k)){
00190                         //$this->xdebug("$k: $v");
00191                         //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
00192                         if($ns_prefix = substr(strrchr($k,':'),1)){
00193                                 //$this->xdebug("Add namespace[$ns_prefix] = $v");
00194                                                 $this->namespaces[$ns_prefix] = $v;
00195                                         } else {
00196                                                 $this->defaultNamespace[$pos] = $v;
00197                                                 if (! $this->getPrefixFromNamespace($v)) {
00198                                                         $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
00199                                                 }
00200                                         }
00201                                         if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
00202                                                 $this->XMLSchemaVersion = $v;
00203                                                 $this->namespaces['xsi'] = $v.'-instance';
00204                                         }
00205                                 }
00206                 }
00207                 foreach($attrs as $k => $v){
00208                 // expand each attribute
00209                 $k = strpos($k,':') ? $this->expandQname($k) : $k;
00210                 $v = strpos($v,':') ? $this->expandQname($v) : $v;
00211                         $eAttrs[$k] = $v;
00212                 }
00213                 $attrs = $eAttrs;
00214         } else {
00215                 $attrs = array();
00216         }
00217                 // find status, register data
00218                 switch($name){
00219                         case 'all':                     // (optional) compositor content for a complexType
00220                         case 'choice':
00221                         case 'group':
00222                         case 'sequence':
00223                                 //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
00224                                 $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
00225                                 //if($name == 'all' || $name == 'sequence'){
00226                                 //      $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
00227                                 //}
00228                         break;
00229                         case 'attribute':       // complexType attribute
00230                 //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
00231                 $this->xdebug("parsing attribute:");
00232                 $this->appendDebug($this->varDump($attrs));
00233                                 if (!isset($attrs['form'])) {
00234                                         $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
00235                                 }
00236                 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
00237                                         $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
00238                                         if (!strpos($v, ':')) {
00239                                                 // no namespace in arrayType attribute value...
00240                                                 if ($this->defaultNamespace[$pos]) {
00241                                                         // ...so use the default
00242                                                         $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
00243                                                 }
00244                                         }
00245                 }
00246                 if(isset($attrs['name'])){
00247                                         $this->attributes[$attrs['name']] = $attrs;
00248                                         $aname = $attrs['name'];
00249                                 } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
00250                                         if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
00251                                 $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
00252                         } else {
00253                                 $aname = '';
00254                         }
00255                                 } elseif(isset($attrs['ref'])){
00256                                         $aname = $attrs['ref'];
00257                     $this->attributes[$attrs['ref']] = $attrs;
00258                                 }
00259                 
00260                                 if($this->currentComplexType){  // This should *always* be
00261                                         $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
00262                                 }
00263                                 // arrayType attribute
00264                                 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
00265                                         $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
00266                         $prefix = $this->getPrefix($aname);
00267                                         if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
00268                                                 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
00269                                         } else {
00270                                                 $v = '';
00271                                         }
00272                     if(strpos($v,'[,]')){
00273                         $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
00274                     }
00275                     $v = substr($v,0,strpos($v,'[')); // clip the []
00276                     if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
00277                         $v = $this->XMLSchemaVersion.':'.$v;
00278                     }
00279                     $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
00280                                 }
00281                         break;
00282                         case 'complexContent':  // (optional) content for a complexType
00283                         break;
00284                         case 'complexType':
00285                                 array_push($this->complexTypeStack, $this->currentComplexType);
00286                                 if(isset($attrs['name'])){
00287                                         $this->xdebug('processing named complexType '.$attrs['name']);
00288                                         //$this->currentElement = false;
00289                                         $this->currentComplexType = $attrs['name'];
00290                                         $this->complexTypes[$this->currentComplexType] = $attrs;
00291                                         $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
00292                                         // This is for constructs like
00293                                         //           <complexType name="ListOfString" base="soap:Array">
00294                                         //                <sequence>
00295                                         //                    <element name="string" type="xsd:string"
00296                                         //                        minOccurs="0" maxOccurs="unbounded" />
00297                                         //                </sequence>
00298                                         //            </complexType>
00299                                         if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
00300                                                 $this->xdebug('complexType is unusual array');
00301                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
00302                                         } else {
00303                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
00304                                         }
00305                                 }else{
00306                                         $this->xdebug('processing unnamed complexType for element '.$this->currentElement);
00307                                         $this->currentComplexType = $this->currentElement . '_ContainedType';
00308                                         //$this->currentElement = false;
00309                                         $this->complexTypes[$this->currentComplexType] = $attrs;
00310                                         $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
00311                                         // This is for constructs like
00312                                         //           <complexType name="ListOfString" base="soap:Array">
00313                                         //                <sequence>
00314                                         //                    <element name="string" type="xsd:string"
00315                                         //                        minOccurs="0" maxOccurs="unbounded" />
00316                                         //                </sequence>
00317                                         //            </complexType>
00318                                         if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
00319                                                 $this->xdebug('complexType is unusual array');
00320                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
00321                                         } else {
00322                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
00323                                         }
00324                                 }
00325                         break;
00326                         case 'element':
00327                                 array_push($this->elementStack, $this->currentElement);
00328                                 // elements defined as part of a complex type should
00329                                 // not really be added to $this->elements, but for some
00330                                 // reason, they are
00331                                 if (!isset($attrs['form'])) {
00332                                         $attrs['form'] = $this->schemaInfo['elementFormDefault'];
00333                                 }
00334                                 if(isset($attrs['type'])){
00335                                         $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
00336                                         if (! $this->getPrefix($attrs['type'])) {
00337                                                 if ($this->defaultNamespace[$pos]) {
00338                                                         $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
00339                                                         $this->xdebug('used default namespace to make type ' . $attrs['type']);
00340                                                 }
00341                                         }
00342                                         // This is for constructs like
00343                                         //           <complexType name="ListOfString" base="soap:Array">
00344                                         //                <sequence>
00345                                         //                    <element name="string" type="xsd:string"
00346                                         //                        minOccurs="0" maxOccurs="unbounded" />
00347                                         //                </sequence>
00348                                         //            </complexType>
00349                                         if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
00350                                                 $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
00351                                                 $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
00352                                         }
00353                                         $this->currentElement = $attrs['name'];
00354                                         $this->elements[ $attrs['name'] ] = $attrs;
00355                                         $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
00356                                         $ename = $attrs['name'];
00357                                 } elseif(isset($attrs['ref'])){
00358                                         $this->xdebug("processing element as ref to ".$attrs['ref']);
00359                                         $this->currentElement = "ref to ".$attrs['ref'];
00360                                         $ename = $this->getLocalPart($attrs['ref']);
00361                                 } else {
00362                                         $this->xdebug("processing untyped element ".$attrs['name']);
00363                                         $this->currentElement = $attrs['name'];
00364                                         $this->elements[ $attrs['name'] ] = $attrs;
00365                                         $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
00366                                         $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
00367                                         $this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
00368                                         $ename = $attrs['name'];
00369                                 }
00370                                 if(isset($ename) && $this->currentComplexType){
00371                                         $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
00372                                 }
00373                         break;
00374                         case 'enumeration':     //      restriction value list member
00375                                 $this->xdebug('enumeration ' . $attrs['value']);
00376                                 if ($this->currentSimpleType) {
00377                                         $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
00378                                 } elseif ($this->currentComplexType) {
00379                                         $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
00380                                 }
00381                         break;
00382                         case 'extension':       // simpleContent or complexContent type extension
00383                                 $this->xdebug('extension ' . $attrs['base']);
00384                                 if ($this->currentComplexType) {
00385                                         $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
00386                                 }
00387                         break;
00388                         case 'import':
00389                             if (isset($attrs['schemaLocation'])) {
00390                                         //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
00391                     $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
00392                                 } else {
00393                                         //$this->xdebug('import namespace ' . $attrs['namespace']);
00394                     $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
00395                                         if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
00396                                                 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
00397                                         }
00398                                 }
00399                         break;
00400                         case 'list':    // simpleType value list
00401                         break;
00402                         case 'restriction':     // simpleType, simpleContent or complexContent value restriction
00403                                 $this->xdebug('restriction ' . $attrs['base']);
00404                                 if($this->currentSimpleType){
00405                                         $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
00406                                 } elseif($this->currentComplexType){
00407                                         $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
00408                                         if(strstr($attrs['base'],':') == ':Array'){
00409                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
00410                                         }
00411                                 }
00412                         break;
00413                         case 'schema':
00414                                 $this->schemaInfo = $attrs;
00415                                 $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
00416                                 if (isset($attrs['targetNamespace'])) {
00417                                         $this->schemaTargetNamespace = $attrs['targetNamespace'];
00418                                 }
00419                                 if (!isset($attrs['elementFormDefault'])) {
00420                                         $this->schemaInfo['elementFormDefault'] = 'unqualified';
00421                                 }
00422                                 if (!isset($attrs['attributeFormDefault'])) {
00423                                         $this->schemaInfo['attributeFormDefault'] = 'unqualified';
00424                                 }
00425                         break;
00426                         case 'simpleContent':   // (optional) content for a complexType
00427                         break;
00428                         case 'simpleType':
00429                                 array_push($this->simpleTypeStack, $this->currentSimpleType);
00430                                 if(isset($attrs['name'])){
00431                                         $this->xdebug("processing simpleType for name " . $attrs['name']);
00432                                         $this->currentSimpleType = $attrs['name'];
00433                                         $this->simpleTypes[ $attrs['name'] ] = $attrs;
00434                                         $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
00435                                         $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
00436                                 } else {
00437                                         $this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
00438                                         $this->currentSimpleType = $this->currentElement . '_ContainedType';
00439                                         //$this->currentElement = false;
00440                                         $this->simpleTypes[$this->currentSimpleType] = $attrs;
00441                                         $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
00442                                 }
00443                         break;
00444                         case 'union':   // simpleType type list
00445                         break;
00446                         default:
00447                                 //$this->xdebug("do not have anything to do for element $name");
00448                 }
00449         }
00450 
00458         function schemaEndElement($parser, $name) {
00459                 // bring depth down a notch
00460                 $this->depth--;
00461                 // position of current element is equal to the last value left in depth_array for my depth
00462                 if(isset($this->depth_array[$this->depth])){
00463                 $pos = $this->depth_array[$this->depth];
00464         }
00465                 // get element prefix
00466                 if ($prefix = $this->getPrefix($name)){
00467                         // get unqualified name
00468                         $name = $this->getLocalPart($name);
00469                 } else {
00470                 $prefix = '';
00471         }
00472                 // move on...
00473                 if($name == 'complexType'){
00474                         $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
00475                         $this->currentComplexType = array_pop($this->complexTypeStack);
00476                         //$this->currentElement = false;
00477                 }
00478                 if($name == 'element'){
00479                         $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
00480                         $this->currentElement = array_pop($this->elementStack);
00481                 }
00482                 if($name == 'simpleType'){
00483                         $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
00484                         $this->currentSimpleType = array_pop($this->simpleTypeStack);
00485                 }
00486         }
00487 
00495         function schemaCharacterData($parser, $data){
00496                 $pos = $this->depth_array[$this->depth - 1];
00497                 $this->message[$pos]['cdata'] .= $data;
00498         }
00499 
00505         function serializeSchema(){
00506 
00507                 $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
00508                 $xml = '';
00509                 // imports
00510                 if (sizeof($this->imports) > 0) {
00511                         foreach($this->imports as $ns => $list) {
00512                                 foreach ($list as $ii) {
00513                                         if ($ii['location'] != '') {
00514                                                 $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
00515                                         } else {
00516                                                 $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
00517                                         }
00518                                 }
00519                         } 
00520                 } 
00521                 // complex types
00522                 foreach($this->complexTypes as $typeName => $attrs){
00523                         $contentStr = '';
00524                         // serialize child elements
00525                         if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
00526                                 foreach($attrs['elements'] as $element => $eParts){
00527                                         if(isset($eParts['ref'])){
00528                                                 $contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
00529                                         } else {
00530                                                 $contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
00531                                                 foreach ($eParts as $aName => $aValue) {
00532                                                         // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
00533                                                         if ($aName != 'name' && $aName != 'type') {
00534                                                                 $contentStr .= " $aName=\"$aValue\"";
00535                                                         }
00536                                                 }
00537                                                 $contentStr .= "/>\n";
00538                                         }
00539                                 }
00540                                 // compositor wraps elements
00541                                 if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
00542                                         $contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
00543                                 }
00544                         }
00545                         // attributes
00546                         if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
00547                                 foreach($attrs['attrs'] as $attr => $aParts){
00548                                         $contentStr .= "    <$schemaPrefix:attribute";
00549                                         foreach ($aParts as $a => $v) {
00550                                                 if ($a == 'ref' || $a == 'type') {
00551                                                         $contentStr .= " $a=\"".$this->contractQName($v).'"';
00552                                                 } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
00553                                                         $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
00554                                                         $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
00555                                                 } else {
00556                                                         $contentStr .= " $a=\"$v\"";
00557                                                 }
00558                                         }
00559                                         $contentStr .= "/>\n";
00560                                 }
00561                         }
00562                         // if restriction
00563                         if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
00564                                 $contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
00565                                 // complex or simple content
00566                                 if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
00567                                         $contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
00568                                 }
00569                         }
00570                         // finalize complex type
00571                         if($contentStr != ''){
00572                                 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
00573                         } else {
00574                                 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
00575                         }
00576                         $xml .= $contentStr;
00577                 }
00578                 // simple types
00579                 if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
00580                         foreach($this->simpleTypes as $typeName => $eParts){
00581                                 $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
00582                                 if (isset($eParts['enumeration'])) {
00583                                         foreach ($eParts['enumeration'] as $e) {
00584                                                 $xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
00585                                         }
00586                                 }
00587                                 $xml .= " </$schemaPrefix:simpleType>";
00588                         }
00589                 }
00590                 // elements
00591                 if(isset($this->elements) && count($this->elements) > 0){
00592                         foreach($this->elements as $element => $eParts){
00593                                 $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
00594                         }
00595                 }
00596                 // attributes
00597                 if(isset($this->attributes) && count($this->attributes) > 0){
00598                         foreach($this->attributes as $attr => $aParts){
00599                                 $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
00600                         }
00601                 }
00602                 // finish 'er up
00603                 $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
00604                 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
00605                         $el .= " xmlns:$nsp=\"$ns\"\n";
00606                 }
00607                 $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
00608                 return $xml;
00609         }
00610 
00617         function xdebug($string){
00618                 $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
00619         }
00620 
00633         function getPHPType($type,$ns){
00634                 if(isset($this->typemap[$ns][$type])){
00635                         //print "found type '$type' and ns $ns in typemap<br>";
00636                         return $this->typemap[$ns][$type];
00637                 } elseif(isset($this->complexTypes[$type])){
00638                         //print "getting type '$type' and ns $ns from complexTypes array<br>";
00639                         return $this->complexTypes[$type]['phpType'];
00640                 }
00641                 return false;
00642         }
00643 
00666         function getTypeDef($type){
00667                 //$this->debug("in getTypeDef for type $type");
00668                 if(isset($this->complexTypes[$type])){
00669                         $this->xdebug("in getTypeDef, found complexType $type");
00670                         return $this->complexTypes[$type];
00671                 } elseif(isset($this->simpleTypes[$type])){
00672                         $this->xdebug("in getTypeDef, found simpleType $type");
00673                         if (!isset($this->simpleTypes[$type]['phpType'])) {
00674                                 // get info for type to tack onto the simple type
00675                                 // TODO: can this ever really apply (i.e. what is a simpleType really?)
00676                                 $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
00677                                 $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
00678                                 $etype = $this->getTypeDef($uqType);
00679                                 if ($etype) {
00680                                         $this->xdebug("in getTypeDef, found type for simpleType $type:");
00681                                         $this->xdebug($this->varDump($etype));
00682                                         if (isset($etype['phpType'])) {
00683                                                 $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
00684                                         }
00685                                         if (isset($etype['elements'])) {
00686                                                 $this->simpleTypes[$type]['elements'] = $etype['elements'];
00687                                         }
00688                                 }
00689                         }
00690                         return $this->simpleTypes[$type];
00691                 } elseif(isset($this->elements[$type])){
00692                         $this->xdebug("in getTypeDef, found element $type");
00693                         if (!isset($this->elements[$type]['phpType'])) {
00694                                 // get info for type to tack onto the element
00695                                 $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
00696                                 $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
00697                                 $etype = $this->getTypeDef($uqType);
00698                                 if ($etype) {
00699                                         $this->xdebug("in getTypeDef, found type for element $type:");
00700                                         $this->xdebug($this->varDump($etype));
00701                                         if (isset($etype['phpType'])) {
00702                                                 $this->elements[$type]['phpType'] = $etype['phpType'];
00703                                         }
00704                                         if (isset($etype['elements'])) {
00705                                                 $this->elements[$type]['elements'] = $etype['elements'];
00706                                         }
00707                                 } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
00708                                         $this->xdebug("in getTypeDef, element $type is an XSD type");
00709                                         $this->elements[$type]['phpType'] = 'scalar';
00710                                 }
00711                         }
00712                         return $this->elements[$type];
00713                 } elseif(isset($this->attributes[$type])){
00714                         $this->xdebug("in getTypeDef, found attribute $type");
00715                         return $this->attributes[$type];
00716                 } elseif (ereg('_ContainedType$', $type)) {
00717                         $this->xdebug("in getTypeDef, have an untyped element $type");
00718                         $typeDef['typeClass'] = 'simpleType';
00719                         $typeDef['phpType'] = 'scalar';
00720                         $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
00721                         return $typeDef;
00722                 }
00723                 $this->xdebug("in getTypeDef, did not find $type");
00724                 return false;
00725         }
00726 
00735     function serializeTypeDef($type){
00736         //print "in sTD() for type $type<br>";
00737         if($typeDef = $this->getTypeDef($type)){
00738                 $str .= '<'.$type;
00739             if(is_array($typeDef['attrs'])){
00740                 foreach($attrs as $attName => $data){
00741                     $str .= " $attName=\"{type = ".$data['type']."}\"";
00742                 }
00743             }
00744             $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
00745             if(count($typeDef['elements']) > 0){
00746                 $str .= ">";
00747                 foreach($typeDef['elements'] as $element => $eData){
00748                     $str .= $this->serializeTypeDef($element);
00749                 }
00750                 $str .= "</$type>";
00751             } elseif($typeDef['typeClass'] == 'element') {
00752                 $str .= "></$type>";
00753             } else {
00754                 $str .= "/>";
00755             }
00756                         return $str;
00757         }
00758         return false;
00759     }
00760 
00771         function typeToForm($name,$type){
00772                 // get typedef
00773                 if($typeDef = $this->getTypeDef($type)){
00774                         // if struct
00775                         if($typeDef['phpType'] == 'struct'){
00776                                 $buffer .= '<table>';
00777                                 foreach($typeDef['elements'] as $child => $childDef){
00778                                         $buffer .= "
00779                                         <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
00780                                         <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
00781                                 }
00782                                 $buffer .= '</table>';
00783                         // if array
00784                         } elseif($typeDef['phpType'] == 'array'){
00785                                 $buffer .= '<table>';
00786                                 for($i=0;$i < 3; $i++){
00787                                         $buffer .= "
00788                                         <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
00789                                         <td><input type='text' name='parameters[".$name."][]'></td></tr>";
00790                                 }
00791                                 $buffer .= '</table>';
00792                         // if scalar
00793                         } else {
00794                                 $buffer .= "<input type='text' name='parameters[$name]'>";
00795                         }
00796                 } else {
00797                         $buffer .= "<input type='text' name='parameters[$name]'>";
00798                 }
00799                 return $buffer;
00800         }
00801         
00843         function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
00844                 $this->complexTypes[$name] = array(
00845             'name'              => $name,
00846             'typeClass' => $typeClass,
00847             'phpType'   => $phpType,
00848                 'compositor'=> $compositor,
00849             'restrictionBase' => $restrictionBase,
00850                 'elements'      => $elements,
00851             'attrs'             => $attrs,
00852             'arrayType' => $arrayType
00853                 );
00854                 
00855                 $this->xdebug("addComplexType $name:");
00856                 $this->appendDebug($this->varDump($this->complexTypes[$name]));
00857         }
00858         
00871         function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
00872                 $this->simpleTypes[$name] = array(
00873             'name'                      => $name,
00874             'typeClass'         => $typeClass,
00875             'phpType'           => $phpType,
00876             'type'                      => $restrictionBase,
00877             'enumeration'       => $enumeration
00878                 );
00879                 
00880                 $this->xdebug("addSimpleType $name:");
00881                 $this->appendDebug($this->varDump($this->simpleTypes[$name]));
00882         }
00883 
00891         function addElement($attrs) {
00892                 if (! $this->getPrefix($attrs['type'])) {
00893                         $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
00894                 }
00895                 $this->elements[ $attrs['name'] ] = $attrs;
00896                 $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
00897                 
00898                 $this->xdebug("addElement " . $attrs['name']);
00899                 $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
00900         }
00901 }
00902 
00903 
00904 
00905 
00906 ?>

Generated on Fri Dec 13 2013 17:57:03 for ILIAS Release_3_9_x_branch .rev 46835 by  doxygen 1.7.1