58 $this->
debug(
'xmlschema class instantiated, inside constructor');
65 $this->namespaces = array_merge($this->namespaces,
$namespaces);
92 $xmlStr = @join(
"",@file(
$xml));
94 $msg =
'Error reading XML from '.$xml;
99 $this->
debug(
"parsing $xml");
101 $this->
debug(
"done parsing $xml");
120 $this->parser = xml_parser_create();
122 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
125 xml_set_object($this->parser, $this);
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');
137 if(!xml_parse($this->parser,
$xml,
true)){
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))
143 $this->
debug($errstr);
148 xml_parser_free($this->parser);
150 $this->
debug(
'no xml passed to parseString()!!');
151 $this->
setError(
'no xml passed to parseString()!!');
166 $pos = $this->position++;
169 $this->depth_array[
$depth] = $pos;
170 $this->message[$pos] = array(
'cdata' =>
'');
172 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[
$depth - 1]];
174 $this->defaultNamespace[$pos] =
false;
186 if(count($attrs) > 0){
187 foreach($attrs as $k => $v){
189 if(ereg(
"^xmlns",$k)){
192 if($ns_prefix = substr(strrchr($k,
':'),1)){
194 $this->namespaces[$ns_prefix] = $v;
196 $this->defaultNamespace[$pos] = $v;
198 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $v;
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';
207 foreach($attrs as $k => $v){
231 $this->
xdebug(
"parsing attribute:");
233 if (!isset($attrs[
'form'])) {
234 $attrs[
'form'] = $this->schemaInfo[
'attributeFormDefault'];
236 if (isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
237 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
238 if (!strpos($v,
':')) {
240 if ($this->defaultNamespace[$pos]) {
242 $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] .
':' . $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
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'];
255 } elseif(isset($attrs[
'ref'])){
256 $aname = $attrs[
'ref'];
257 $this->attributes[$attrs[
'ref']] = $attrs;
260 if($this->currentComplexType){
264 if(isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->
getLocalPart($aname) ==
'arrayType'){
267 if(isset($attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'])){
268 $v = $attrs[
'http://schemas.xmlsoap.org/wsdl/:arrayType'];
272 if(strpos($v,
'[,]')){
275 $v = substr($v,0,strpos($v,
'['));
276 if(!strpos($v,
':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
277 $v = $this->XMLSchemaVersion.
':'.$v;
282 case 'complexContent':
285 array_push($this->complexTypeStack, $this->currentComplexType);
286 if(isset($attrs[
'name'])){
287 $this->
xdebug(
'processing named complexType '.$attrs[
'name']);
289 $this->currentComplexType = $attrs[
'name'];
299 if(isset($attrs[
'base']) && ereg(
':Array$',$attrs[
'base'])){
300 $this->
xdebug(
'complexType is unusual array');
306 $this->
xdebug(
'processing unnamed complexType for element '.$this->currentElement);
307 $this->currentComplexType = $this->currentElement .
'_ContainedType';
318 if(isset($attrs[
'base']) && ereg(
':Array$',$attrs[
'base'])){
319 $this->
xdebug(
'complexType is unusual array');
327 array_push($this->elementStack, $this->currentElement);
331 if (!isset($attrs[
'form'])) {
332 $attrs[
'form'] = $this->schemaInfo[
'elementFormDefault'];
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']);
349 if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType][
'phpType'] ==
'array') {
350 $this->
xdebug(
'arrayType for unusual array is ' . $attrs[
'type']);
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'];
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'];
370 if(isset($ename) && $this->currentComplexType){
375 $this->
xdebug(
'enumeration ' . $attrs[
'value']);
376 if ($this->currentSimpleType) {
378 } elseif ($this->currentComplexType) {
383 $this->
xdebug(
'extension ' . $attrs[
'base']);
384 if ($this->currentComplexType) {
389 if (isset($attrs[
'schemaLocation'])) {
391 $this->imports[$attrs[
'namespace']][] = array(
'location' => $attrs[
'schemaLocation'],
'loaded' =>
false);
394 $this->imports[$attrs[
'namespace']][] = array(
'location' =>
'',
'loaded' =>
true);
396 $this->namespaces[
'ns'.(count($this->namespaces)+1)] = $attrs[
'namespace'];
403 $this->
xdebug(
'restriction ' . $attrs[
'base']);
404 if($this->currentSimpleType){
406 } elseif($this->currentComplexType){
408 if(strstr($attrs[
'base'],
':') ==
':Array'){
414 $this->schemaInfo = $attrs;
416 if (isset($attrs[
'targetNamespace'])) {
417 $this->schemaTargetNamespace = $attrs[
'targetNamespace'];
419 if (!isset($attrs[
'elementFormDefault'])) {
420 $this->schemaInfo[
'elementFormDefault'] =
'unqualified';
422 if (!isset($attrs[
'attributeFormDefault'])) {
423 $this->schemaInfo[
'attributeFormDefault'] =
'unqualified';
426 case 'simpleContent':
429 array_push($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';
437 $this->
xdebug(
'processing unnamed simpleType for element '.$this->currentElement);
438 $this->currentSimpleType = $this->currentElement .
'_ContainedType';
462 if(isset($this->depth_array[$this->depth])){
473 if($name ==
'complexType'){
474 $this->
xdebug(
'done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType :
'(unknown)'));
475 $this->currentComplexType = array_pop($this->complexTypeStack);
478 if($name ==
'element'){
479 $this->
xdebug(
'done processing element ' . ($this->currentElement ? $this->currentElement :
'(unknown)'));
480 $this->currentElement = array_pop($this->elementStack);
482 if($name ==
'simpleType'){
483 $this->
xdebug(
'done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType :
'(unknown)'));
484 $this->currentSimpleType = array_pop($this->simpleTypeStack);
496 $pos = $this->depth_array[$this->depth - 1];
497 $this->message[$pos][
'cdata'] .=
$data;
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";
516 $xml .=
" <$schemaPrefix:import namespace=\"" . $ns .
"\" />\n";
522 foreach($this->complexTypes as $typeName => $attrs){
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";
530 $contentStr .=
" <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts[
'type']) .
"\"";
531 foreach ($eParts as $aName => $aValue) {
533 if ($aName !=
'name' && $aName !=
'type') {
534 $contentStr .=
" $aName=\"$aValue\"";
537 $contentStr .=
"/>\n";
541 if (isset($attrs[
'compositor']) && ($attrs[
'compositor'] !=
'')) {
542 $contentStr =
" <$schemaPrefix:$attrs[compositor]>\n".$contentStr.
" </$schemaPrefix:$attrs[compositor]>\n";
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).
'"';
556 $contentStr .=
" $a=\"$v\"";
559 $contentStr .=
"/>\n";
563 if (isset($attrs[
'restrictionBase']) && $attrs[
'restrictionBase'] !=
''){
564 $contentStr =
" <$schemaPrefix:restriction base=\"".$this->contractQName($attrs[
'restrictionBase']).
"\">\n".$contentStr.
" </$schemaPrefix:restriction>\n";
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";
571 if($contentStr !=
''){
572 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr.
" </$schemaPrefix:complexType>\n";
574 $contentStr =
" <$schemaPrefix:complexType name=\"$typeName\"/>\n";
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";
587 $xml .=
" </$schemaPrefix:simpleType>";
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";
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/>";
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";
607 $xml = $el .
">\n".$xml.
"</$schemaPrefix:schema>\n";
618 $this->
debug(
'<' . $this->schemaTargetNamespace .
'> '.$string);
634 if(isset($this->typemap[$ns][$type])){
636 return $this->typemap[$ns][$type];
637 } elseif(isset($this->complexTypes[$type])){
639 return $this->complexTypes[$type][
'phpType'];
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'])) {
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'],
':'));
680 $this->
xdebug(
"in getTypeDef, found type for simpleType $type:");
682 if (isset($etype[
'phpType'])) {
683 $this->simpleTypes[$type][
'phpType'] = $etype[
'phpType'];
685 if (isset($etype[
'elements'])) {
686 $this->simpleTypes[$type][
'elements'] = $etype[
'elements'];
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'])) {
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'],
':'));
699 $this->
xdebug(
"in getTypeDef, found type for element $type:");
701 if (isset($etype[
'phpType'])) {
702 $this->elements[$type][
'phpType'] = $etype[
'phpType'];
704 if (isset($etype[
'elements'])) {
705 $this->elements[$type][
'elements'] = $etype[
'elements'];
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';
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';
723 $this->
xdebug(
"in getTypeDef, did not find $type");
739 if(is_array($typeDef[
'attrs'])){
740 foreach($attrs as $attName =>
$data){
741 $str .=
" $attName=\"{type = ".$data[
'type'].
"}\"";
744 $str .=
" xmlns=\"".$this->schema[
'targetNamespace'].
"\"";
745 if(count($typeDef[
'elements']) > 0){
747 foreach($typeDef[
'elements'] as $element => $eData){
751 } elseif($typeDef[
'typeClass'] ==
'element') {
775 if($typeDef[
'phpType'] ==
'struct'){
776 $buffer .=
'<table>';
777 foreach($typeDef[
'elements'] as $child => $childDef){
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>";
782 $buffer .=
'</table>';
784 } elseif($typeDef[
'phpType'] ==
'array'){
785 $buffer .=
'<table>';
786 for($i=0;$i < 3; $i++){
788 <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
789 <td><input type='text' name='parameters[".$name.
"][]'></td></tr>";
791 $buffer .=
'</table>';
794 $buffer .=
"<input type='text' name='parameters[$name]'>";
797 $buffer .=
"<input type='text' name='parameters[$name]'>";
843 function addComplexType($name,$typeClass=
'complexType',$phpType=
'array',$compositor=
'',$restrictionBase=
'',
$elements=array(),$attrs=array(),$arrayType=
''){
844 $this->complexTypes[$name] = array(
846 'typeClass' => $typeClass,
847 'phpType' => $phpType,
848 'compositor'=> $compositor,
849 'restrictionBase' => $restrictionBase,
852 'arrayType' => $arrayType
855 $this->
xdebug(
"addComplexType $name:");
871 function addSimpleType($name, $restrictionBase=
'', $typeClass=
'simpleType', $phpType=
'scalar', $enumeration=array()) {
872 $this->simpleTypes[$name] = array(
874 'typeClass' => $typeClass,
875 'phpType' => $phpType,
876 'type' => $restrictionBase,
877 'enumeration' => $enumeration
880 $this->
xdebug(
"addSimpleType $name:");
892 if (! $this->
getPrefix($attrs[
'type'])) {
893 $attrs[
'type'] = $this->schemaTargetNamespace .
':' . $attrs[
'type'];
895 $this->elements[ $attrs[
'name'] ] = $attrs;
896 $this->elements[ $attrs[
'name'] ][
'typeClass'] =
'element';
898 $this->
xdebug(
"addElement " . $attrs[
'name']);