You are here

function XMLSchema::schemaStartElement in Salesforce Suite 5

Same name in this branch
  1. 5 includes/nusoap.php \XMLSchema::schemaStartElement()
  2. 5 includes/nusoap.orig.php \XMLSchema::schemaStartElement()
Same name and namespace in other branches
  1. 5.2 includes/nusoap.php \XMLSchema::schemaStartElement()
  2. 5.2 includes/nusoap.orig.php \XMLSchema::schemaStartElement()

* start-element handler * *

Parameters

string $parser XML parser object: * @param string $name element name * @param string $attrs associative array of attributes * @access private

File

includes/nusoap.php, line 1149

Class

XMLSchema
parses an XML Schema, allows access to it's data, other utility methods no validation... yet. very experimental and limited. As is discussed on XML-DEV, I'm one of the people that just doesn't have time to read the spec(s) thoroughly,…

Code

function schemaStartElement($parser, $name, $attrs) {

  // position in the total number of elements, starting from 0
  $pos = $this->position++;
  $depth = $this->depth++;

  // set self as current value for this depth
  $this->depth_array[$depth] = $pos;
  $this->message[$pos] = array(
    'cdata' => '',
  );
  if ($depth > 0) {
    $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
  }
  else {
    $this->defaultNamespace[$pos] = false;
  }

  // get element prefix
  if ($prefix = $this
    ->getPrefix($name)) {

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

  // loop thru attributes, expanding, and registering namespace declarations
  if (count($attrs) > 0) {
    foreach ($attrs as $k => $v) {

      // if ns declarations, add to class level array of valid namespaces
      if (ereg("^xmlns", $k)) {

        //$this->xdebug("$k: $v");

        //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
        if ($ns_prefix = substr(strrchr($k, ':'), 1)) {

          //$this->xdebug("Add namespace[$ns_prefix] = $v");
          $this->namespaces[$ns_prefix] = $v;
        }
        else {
          $this->defaultNamespace[$pos] = $v;
          if (!$this
            ->getPrefixFromNamespace($v)) {
            $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
          }
        }
        if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
          $this->XMLSchemaVersion = $v;
          $this->namespaces['xsi'] = $v . '-instance';
        }
      }
    }
    foreach ($attrs as $k => $v) {

      // expand each attribute
      $k = strpos($k, ':') ? $this
        ->expandQname($k) : $k;
      $v = strpos($v, ':') ? $this
        ->expandQname($v) : $v;
      $eAttrs[$k] = $v;
    }
    $attrs = $eAttrs;
  }
  else {
    $attrs = array();
  }

  // find status, register data
  switch ($name) {
    case 'all':

    // (optional) compositor content for a complexType
    case 'choice':
    case 'group':
    case 'sequence':

      //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
      $this->complexTypes[$this->currentComplexType]['compositor'] = $name;

      //if($name == 'all' || $name == 'sequence'){

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

      //}
      break;
    case 'attribute':

      // complexType attribute

      //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
      $this
        ->xdebug("parsing attribute:");
      $this
        ->appendDebug($this
        ->varDump($attrs));
      if (!isset($attrs['form'])) {
        $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
      }
      if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
        $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
        if (!strpos($v, ':')) {

          // no namespace in arrayType attribute value...
          if ($this->defaultNamespace[$pos]) {

            // ...so use the default
            $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
          }
        }
      }
      if (isset($attrs['name'])) {
        $this->attributes[$attrs['name']] = $attrs;
        $aname = $attrs['name'];
      }
      elseif (isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType') {
        if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
          $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
        }
        else {
          $aname = '';
        }
      }
      elseif (isset($attrs['ref'])) {
        $aname = $attrs['ref'];
        $this->attributes[$attrs['ref']] = $attrs;
      }
      if ($this->currentComplexType) {

        // This should *always* be
        $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
      }

      // arrayType attribute
      if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this
        ->getLocalPart($aname) == 'arrayType') {
        $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
        $prefix = $this
          ->getPrefix($aname);
        if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
          $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
        }
        else {
          $v = '';
        }
        if (strpos($v, '[,]')) {
          $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
        }
        $v = substr($v, 0, strpos($v, '['));

        // clip the []
        if (!strpos($v, ':') && isset($this->typemap[$this->XMLSchemaVersion][$v])) {
          $v = $this->XMLSchemaVersion . ':' . $v;
        }
        $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
      }
      break;
    case 'complexContent':

      // (optional) content for a complexType
      break;
    case 'complexType':
      array_push($this->complexTypeStack, $this->currentComplexType);
      if (isset($attrs['name'])) {
        $this
          ->xdebug('processing named complexType ' . $attrs['name']);

        //$this->currentElement = false;
        $this->currentComplexType = $attrs['name'];
        $this->complexTypes[$this->currentComplexType] = $attrs;
        $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';

        // This is for constructs like
        //           <complexType name="ListOfString" base="soap:Array">
        //                <sequence>
        //                    <element name="string" type="xsd:string"
        //                        minOccurs="0" maxOccurs="unbounded" />
        //                </sequence>
        //            </complexType>
        if (isset($attrs['base']) && ereg(':Array$', $attrs['base'])) {
          $this
            ->xdebug('complexType is unusual array');
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
        }
        else {
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
        }
      }
      else {
        $this
          ->xdebug('processing unnamed complexType for element ' . $this->currentElement);
        $this->currentComplexType = $this->currentElement . '_ContainedType';

        //$this->currentElement = false;
        $this->complexTypes[$this->currentComplexType] = $attrs;
        $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';

        // This is for constructs like
        //           <complexType name="ListOfString" base="soap:Array">
        //                <sequence>
        //                    <element name="string" type="xsd:string"
        //                        minOccurs="0" maxOccurs="unbounded" />
        //                </sequence>
        //            </complexType>
        if (isset($attrs['base']) && ereg(':Array$', $attrs['base'])) {
          $this
            ->xdebug('complexType is unusual array');
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
        }
        else {
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
        }
      }
      break;
    case 'element':
      array_push($this->elementStack, $this->currentElement);

      // elements defined as part of a complex type should
      // not really be added to $this->elements, but for some
      // reason, they are
      if (!isset($attrs['form'])) {
        $attrs['form'] = $this->schemaInfo['elementFormDefault'];
      }
      if (isset($attrs['type'])) {
        $this
          ->xdebug("processing typed element " . $attrs['name'] . " of type " . $attrs['type']);
        if (!$this
          ->getPrefix($attrs['type'])) {
          if ($this->defaultNamespace[$pos]) {
            $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
            $this
              ->xdebug('used default namespace to make type ' . $attrs['type']);
          }
        }

        // This is for constructs like
        //           <complexType name="ListOfString" base="soap:Array">
        //                <sequence>
        //                    <element name="string" type="xsd:string"
        //                        minOccurs="0" maxOccurs="unbounded" />
        //                </sequence>
        //            </complexType>
        if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
          $this
            ->xdebug('arrayType for unusual array is ' . $attrs['type']);
          $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
        }
        $this->currentElement = $attrs['name'];
        $this->elements[$attrs['name']] = $attrs;
        $this->elements[$attrs['name']]['typeClass'] = 'element';
        $ename = $attrs['name'];
      }
      elseif (isset($attrs['ref'])) {
        $this
          ->xdebug("processing element as ref to " . $attrs['ref']);
        $this->currentElement = "ref to " . $attrs['ref'];
        $ename = $this
          ->getLocalPart($attrs['ref']);
      }
      else {
        $this
          ->xdebug("processing untyped element " . $attrs['name']);
        $this->currentElement = $attrs['name'];
        $this->elements[$attrs['name']] = $attrs;
        $this->elements[$attrs['name']]['typeClass'] = 'element';
        $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
        $this->elements[$attrs['name']]['type'] = $attrs['type'];
        $ename = $attrs['name'];
      }
      if (isset($ename) && $this->currentComplexType) {
        $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
      }
      break;
    case 'enumeration':

      //	restriction value list member
      $this
        ->xdebug('enumeration ' . $attrs['value']);
      if ($this->currentSimpleType) {
        $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
      }
      elseif ($this->currentComplexType) {
        $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
      }
      break;
    case 'extension':

      // simpleContent or complexContent type extension
      $this
        ->xdebug('extension ' . $attrs['base']);
      if ($this->currentComplexType) {
        $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
      }
      break;
    case 'import':
      if (isset($attrs['schemaLocation'])) {

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

        //$this->xdebug('import namespace ' . $attrs['namespace']);
        $this->imports[$attrs['namespace']][] = array(
          'location' => '',
          'loaded' => true,
        );
        if (!$this
          ->getPrefixFromNamespace($attrs['namespace'])) {
          $this->namespaces['ns' . (count($this->namespaces) + 1)] = $attrs['namespace'];
        }
      }
      break;
    case 'list':

      // simpleType value list
      break;
    case 'restriction':

      // simpleType, simpleContent or complexContent value restriction
      $this
        ->xdebug('restriction ' . $attrs['base']);
      if ($this->currentSimpleType) {
        $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
      }
      elseif ($this->currentComplexType) {
        $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
        if (strstr($attrs['base'], ':') == ':Array') {
          $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
        }
      }
      break;
    case 'schema':
      $this->schemaInfo = $attrs;
      $this->schemaInfo['schemaVersion'] = $this
        ->getNamespaceFromPrefix($prefix);
      if (isset($attrs['targetNamespace'])) {
        $this->schemaTargetNamespace = $attrs['targetNamespace'];
      }
      if (!isset($attrs['elementFormDefault'])) {
        $this->schemaInfo['elementFormDefault'] = 'unqualified';
      }
      if (!isset($attrs['attributeFormDefault'])) {
        $this->schemaInfo['attributeFormDefault'] = 'unqualified';
      }
      break;
    case 'simpleContent':

      // (optional) content for a complexType
      break;
    case 'simpleType':
      array_push($this->simpleTypeStack, $this->currentSimpleType);
      if (isset($attrs['name'])) {
        $this
          ->xdebug("processing simpleType for name " . $attrs['name']);
        $this->currentSimpleType = $attrs['name'];
        $this->simpleTypes[$attrs['name']] = $attrs;
        $this->simpleTypes[$attrs['name']]['typeClass'] = 'simpleType';
        $this->simpleTypes[$attrs['name']]['phpType'] = 'scalar';
      }
      else {
        $this
          ->xdebug('processing unnamed simpleType for element ' . $this->currentElement);
        $this->currentSimpleType = $this->currentElement . '_ContainedType';

        //$this->currentElement = false;
        $this->simpleTypes[$this->currentSimpleType] = $attrs;
        $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
      }
      break;
    case 'union':

      // simpleType type list
      break;
    default:
  }
}