Annotation of embedaddon/php/ext/soap/php_schema.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Authors: Brad Lafountain <rodif_bl@yahoo.com> |
! 16: | Shane Caraveo <shane@caraveo.com> |
! 17: | Dmitry Stogov <dmitry@zend.com> |
! 18: +----------------------------------------------------------------------+
! 19: */
! 20: /* $Id: php_schema.c 321634 2012-01-01 13:15:04Z felipe $ */
! 21:
! 22: #include "php_soap.h"
! 23: #include "libxml/uri.h"
! 24:
! 25: static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type);
! 26: static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type);
! 27: static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type);
! 28: static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type);
! 29: static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type);
! 30: static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type, int simpleType);
! 31: static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type);
! 32: static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type);
! 33: static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type);
! 34: static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model);
! 35: static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type, sdlContentModelPtr model);
! 36: static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model);
! 37: static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model);
! 38: static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type, sdlContentModelPtr model);
! 39: static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model);
! 40: static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx);
! 41: static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx);
! 42:
! 43: static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr);
! 44:
! 45: static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr);
! 46:
! 47: static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type);
! 48:
! 49: static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
! 50: {
! 51: smart_str nscat = {0};
! 52: encodePtr enc, *enc_ptr;
! 53:
! 54: if (sdl->encoders == NULL) {
! 55: sdl->encoders = emalloc(sizeof(HashTable));
! 56: zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
! 57: }
! 58: smart_str_appends(&nscat, (char*)ns);
! 59: smart_str_appendc(&nscat, ':');
! 60: smart_str_appends(&nscat, (char*)type);
! 61: smart_str_0(&nscat);
! 62: if (zend_hash_find(sdl->encoders, nscat.c, nscat.len + 1, (void**)&enc_ptr) == SUCCESS) {
! 63: enc = *enc_ptr;
! 64: if (enc->details.ns) {
! 65: efree(enc->details.ns);
! 66: }
! 67: if (enc->details.type_str) {
! 68: efree(enc->details.type_str);
! 69: }
! 70: } else {
! 71: enc_ptr = NULL;
! 72: enc = emalloc(sizeof(encode));
! 73: }
! 74: memset(enc, 0, sizeof(encode));
! 75:
! 76: enc->details.ns = estrdup((char*)ns);
! 77: enc->details.type_str = estrdup((char*)type);
! 78: enc->details.sdl_type = cur_type;
! 79: enc->to_xml = sdl_guess_convert_xml;
! 80: enc->to_zval = sdl_guess_convert_zval;
! 81:
! 82: if (enc_ptr == NULL) {
! 83: zend_hash_update(sdl->encoders, nscat.c, nscat.len + 1, &enc, sizeof(encodePtr), NULL);
! 84: }
! 85: smart_str_free(&nscat);
! 86: return enc;
! 87: }
! 88:
! 89: static encodePtr get_create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const xmlChar *ns, const xmlChar *type)
! 90: {
! 91: encodePtr enc = get_encoder(sdl, (char*)ns, (char*)type);
! 92: if (enc == NULL) {
! 93: enc = create_encoder(sdl, cur_type, ns, type);
! 94: }
! 95: return enc;
! 96: }
! 97:
! 98: static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlAttrPtr tns, int import TSRMLS_DC) {
! 99: if (location != NULL &&
! 100: !zend_hash_exists(&ctx->docs, (char*)location, xmlStrlen(location)+1)) {
! 101: xmlDocPtr doc;
! 102: xmlNodePtr schema;
! 103: xmlAttrPtr new_tns;
! 104:
! 105: sdl_set_uri_credentials(ctx, (char*)location TSRMLS_CC);
! 106: doc = soap_xmlParseFile((char*)location TSRMLS_CC);
! 107: sdl_restore_uri_credentials(ctx TSRMLS_CC);
! 108:
! 109: if (doc == NULL) {
! 110: soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
! 111: }
! 112: schema = get_node(doc->children, "schema");
! 113: if (schema == NULL) {
! 114: xmlFreeDoc(doc);
! 115: soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location);
! 116: }
! 117: new_tns = get_attribute(schema->properties, "targetNamespace");
! 118: if (import) {
! 119: if (ns != NULL && (new_tns == NULL || xmlStrcmp(ns->children->content, new_tns->children->content) != 0)) {
! 120: xmlFreeDoc(doc);
! 121: soap_error2(E_ERROR, "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'", location, ns->children->content);
! 122: }
! 123: if (ns == NULL && new_tns != NULL) {
! 124: xmlFreeDoc(doc);
! 125: soap_error2(E_ERROR, "Parsing Schema: can't import schema from '%s', unexpected 'targetNamespace'='%s'", location, new_tns->children->content);
! 126: }
! 127: } else {
! 128: new_tns = get_attribute(schema->properties, "targetNamespace");
! 129: if (new_tns == NULL) {
! 130: if (tns != NULL) {
! 131: xmlSetProp(schema, BAD_CAST("targetNamespace"), tns->children->content);
! 132: }
! 133: } else if (tns != NULL && xmlStrcmp(tns->children->content, new_tns->children->content) != 0) {
! 134: xmlFreeDoc(doc);
! 135: soap_error1(E_ERROR, "Parsing Schema: can't include schema from '%s', different 'targetNamespace'", location);
! 136: }
! 137: }
! 138: zend_hash_add(&ctx->docs, (char*)location, xmlStrlen(location)+1, (void**)&doc, sizeof(xmlDocPtr), NULL);
! 139: load_schema(ctx, schema TSRMLS_CC);
! 140: }
! 141: }
! 142:
! 143: /*
! 144: 2.6.1 xsi:type
! 145: 2.6.2 xsi:nil
! 146: 2.6.3 xsi:schemaLocation, xsi:noNamespaceSchemaLocation
! 147: */
! 148:
! 149: /*
! 150: <schema
! 151: attributeFormDefault = (qualified | unqualified) : unqualified
! 152: blockDefault = (#all | List of (extension | restriction | substitution)) : ''
! 153: elementFormDefault = (qualified | unqualified) : unqualified
! 154: finalDefault = (#all | List of (extension | restriction)) : ''
! 155: id = ID
! 156: targetNamespace = anyURI
! 157: version = token
! 158: xml:lang = language
! 159: {any attributes with non-schema namespace . . .}>
! 160: Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
! 161: </schema>
! 162: */
! 163: int load_schema(sdlCtx *ctx, xmlNodePtr schema TSRMLS_DC)
! 164: {
! 165: xmlNodePtr trav;
! 166: xmlAttrPtr tns;
! 167:
! 168: if (!ctx->sdl->types) {
! 169: ctx->sdl->types = emalloc(sizeof(HashTable));
! 170: zend_hash_init(ctx->sdl->types, 0, NULL, delete_type, 0);
! 171: }
! 172: if (!ctx->attributes) {
! 173: ctx->attributes = emalloc(sizeof(HashTable));
! 174: zend_hash_init(ctx->attributes, 0, NULL, delete_attribute, 0);
! 175: }
! 176: if (!ctx->attributeGroups) {
! 177: ctx->attributeGroups = emalloc(sizeof(HashTable));
! 178: zend_hash_init(ctx->attributeGroups, 0, NULL, delete_type, 0);
! 179: }
! 180:
! 181: tns = get_attribute(schema->properties, "targetNamespace");
! 182: if (tns == NULL) {
! 183: tns = xmlSetProp(schema, BAD_CAST("targetNamespace"), BAD_CAST(""));
! 184: xmlNewNs(schema, BAD_CAST(""), NULL);
! 185: }
! 186:
! 187: trav = schema->children;
! 188: while (trav != NULL) {
! 189: if (node_is_equal(trav,"include")) {
! 190: xmlAttrPtr location;
! 191:
! 192: location = get_attribute(trav->properties, "schemaLocation");
! 193: if (location == NULL) {
! 194: soap_error0(E_ERROR, "Parsing Schema: include has no 'schemaLocation' attribute");
! 195: } else {
! 196: xmlChar *uri;
! 197: xmlChar *base = xmlNodeGetBase(trav->doc, trav);
! 198:
! 199: if (base == NULL) {
! 200: uri = xmlBuildURI(location->children->content, trav->doc->URL);
! 201: } else {
! 202: uri = xmlBuildURI(location->children->content, base);
! 203: xmlFree(base);
! 204: }
! 205: schema_load_file(ctx, NULL, uri, tns, 0 TSRMLS_CC);
! 206: xmlFree(uri);
! 207: }
! 208:
! 209: } else if (node_is_equal(trav,"redefine")) {
! 210: xmlAttrPtr location;
! 211:
! 212: location = get_attribute(trav->properties, "schemaLocation");
! 213: if (location == NULL) {
! 214: soap_error0(E_ERROR, "Parsing Schema: redefine has no 'schemaLocation' attribute");
! 215: } else {
! 216: xmlChar *uri;
! 217: xmlChar *base = xmlNodeGetBase(trav->doc, trav);
! 218:
! 219: if (base == NULL) {
! 220: uri = xmlBuildURI(location->children->content, trav->doc->URL);
! 221: } else {
! 222: uri = xmlBuildURI(location->children->content, base);
! 223: xmlFree(base);
! 224: }
! 225: schema_load_file(ctx, NULL, uri, tns, 0 TSRMLS_CC);
! 226: xmlFree(uri);
! 227: /* TODO: <redefine> support */
! 228: }
! 229:
! 230: } else if (node_is_equal(trav,"import")) {
! 231: xmlAttrPtr ns, location;
! 232: xmlChar *uri = NULL;
! 233:
! 234: ns = get_attribute(trav->properties, "namespace");
! 235: location = get_attribute(trav->properties, "schemaLocation");
! 236:
! 237: if (ns != NULL && tns != NULL && xmlStrcmp(ns->children->content, tns->children->content) == 0) {
! 238: if (location) {
! 239: soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s', namespace must not match the enclosing schema 'targetNamespace'", location->children->content);
! 240: } else {
! 241: soap_error0(E_ERROR, "Parsing Schema: can't import schema. Namespace must not match the enclosing schema 'targetNamespace'");
! 242: }
! 243: }
! 244: if (location) {
! 245: xmlChar *base = xmlNodeGetBase(trav->doc, trav);
! 246:
! 247: if (base == NULL) {
! 248: uri = xmlBuildURI(location->children->content, trav->doc->URL);
! 249: } else {
! 250: uri = xmlBuildURI(location->children->content, base);
! 251: xmlFree(base);
! 252: }
! 253: }
! 254: schema_load_file(ctx, ns, uri, tns, 1 TSRMLS_CC);
! 255: if (uri != NULL) {xmlFree(uri);}
! 256: } else if (node_is_equal(trav,"annotation")) {
! 257: /* TODO: <annotation> support */
! 258: /* annotation cleanup
! 259: xmlNodePtr tmp = trav;
! 260: trav = trav->next;
! 261: xmlUnlinkNode(tmp);
! 262: xmlFreeNode(tmp);
! 263: continue;
! 264: */
! 265: } else {
! 266: break;
! 267: }
! 268: trav = trav->next;
! 269: }
! 270:
! 271: while (trav != NULL) {
! 272: if (node_is_equal(trav,"simpleType")) {
! 273: schema_simpleType(ctx->sdl, tns, trav, NULL);
! 274: } else if (node_is_equal(trav,"complexType")) {
! 275: schema_complexType(ctx->sdl, tns, trav, NULL);
! 276: } else if (node_is_equal(trav,"group")) {
! 277: schema_group(ctx->sdl, tns, trav, NULL, NULL);
! 278: } else if (node_is_equal(trav,"attributeGroup")) {
! 279: schema_attributeGroup(ctx->sdl, tns, trav, NULL, ctx);
! 280: } else if (node_is_equal(trav,"element")) {
! 281: schema_element(ctx->sdl, tns, trav, NULL, NULL);
! 282: } else if (node_is_equal(trav,"attribute")) {
! 283: schema_attribute(ctx->sdl, tns, trav, NULL, ctx);
! 284: } else if (node_is_equal(trav,"notation")) {
! 285: /* TODO: <notation> support */
! 286: } else if (node_is_equal(trav,"annotation")) {
! 287: /* TODO: <annotation> support */
! 288: } else {
! 289: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in schema", trav->name);
! 290: }
! 291: trav = trav->next;
! 292: }
! 293: return TRUE;
! 294: }
! 295:
! 296: /*
! 297: <simpleType
! 298: final = (#all | (list | union | restriction))
! 299: id = ID
! 300: name = NCName
! 301: {any attributes with non-schema namespace . . .}>
! 302: Content: (annotation?, (restriction | list | union))
! 303: </simpleType>
! 304: */
! 305: static int schema_simpleType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpleType, sdlTypePtr cur_type)
! 306: {
! 307: xmlNodePtr trav;
! 308: xmlAttrPtr name, ns;
! 309:
! 310: ns = get_attribute(simpleType->properties, "targetNamespace");
! 311: if (ns == NULL) {
! 312: ns = tns;
! 313: }
! 314:
! 315: name = get_attribute(simpleType->properties, "name");
! 316: if (cur_type != NULL) {
! 317: /* Anonymous type inside <element> or <restriction> */
! 318: sdlTypePtr newType, *ptr;
! 319:
! 320: newType = emalloc(sizeof(sdlType));
! 321: memset(newType, 0, sizeof(sdlType));
! 322: newType->kind = XSD_TYPEKIND_SIMPLE;
! 323: if (name != NULL) {
! 324: newType->name = estrdup((char*)name->children->content);
! 325: newType->namens = estrdup((char*)ns->children->content);
! 326: } else {
! 327: newType->name = estrdup(cur_type->name);
! 328: newType->namens = estrdup(cur_type->namens);
! 329: }
! 330:
! 331: zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
! 332:
! 333: if (sdl->encoders == NULL) {
! 334: sdl->encoders = emalloc(sizeof(HashTable));
! 335: zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
! 336: }
! 337: cur_type->encode = emalloc(sizeof(encode));
! 338: memset(cur_type->encode, 0, sizeof(encode));
! 339: cur_type->encode->details.ns = estrdup(newType->namens);
! 340: cur_type->encode->details.type_str = estrdup(newType->name);
! 341: cur_type->encode->details.sdl_type = *ptr;
! 342: cur_type->encode->to_xml = sdl_guess_convert_xml;
! 343: cur_type->encode->to_zval = sdl_guess_convert_zval;
! 344: zend_hash_next_index_insert(sdl->encoders, &cur_type->encode, sizeof(encodePtr), NULL);
! 345:
! 346: cur_type =*ptr;
! 347:
! 348: } else if (name != NULL) {
! 349: sdlTypePtr newType, *ptr;
! 350:
! 351: newType = emalloc(sizeof(sdlType));
! 352: memset(newType, 0, sizeof(sdlType));
! 353: newType->kind = XSD_TYPEKIND_SIMPLE;
! 354: newType->name = estrdup((char*)name->children->content);
! 355: newType->namens = estrdup((char*)ns->children->content);
! 356:
! 357: if (cur_type == NULL) {
! 358: zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
! 359: } else {
! 360: if (cur_type->elements == NULL) {
! 361: cur_type->elements = emalloc(sizeof(HashTable));
! 362: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
! 363: }
! 364: zend_hash_update(cur_type->elements, newType->name, strlen(newType->name)+1, &newType, sizeof(sdlTypePtr), (void **)&ptr);
! 365: }
! 366: cur_type = (*ptr);
! 367:
! 368: create_encoder(sdl, cur_type, ns->children->content, name->children->content);
! 369: } else {
! 370: soap_error0(E_ERROR, "Parsing Schema: simpleType has no 'name' attribute");
! 371: }
! 372:
! 373: trav = simpleType->children;
! 374: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 375: /* TODO: <annotation> support */
! 376: trav = trav->next;
! 377: }
! 378: if (trav != NULL) {
! 379: if (node_is_equal(trav,"restriction")) {
! 380: schema_restriction_simpleContent(sdl, tns, trav, cur_type, 1);
! 381: trav = trav->next;
! 382: } else if (node_is_equal(trav,"list")) {
! 383: cur_type->kind = XSD_TYPEKIND_LIST;
! 384: schema_list(sdl, tns, trav, cur_type);
! 385: trav = trav->next;
! 386: } else if (node_is_equal(trav,"union")) {
! 387: cur_type->kind = XSD_TYPEKIND_UNION;
! 388: schema_union(sdl, tns, trav, cur_type);
! 389: trav = trav->next;
! 390: } else {
! 391: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
! 392: }
! 393: } else {
! 394: soap_error0(E_ERROR, "Parsing Schema: expected <restriction>, <list> or <union> in simpleType");
! 395: }
! 396: if (trav != NULL) {
! 397: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleType", trav->name);
! 398: }
! 399:
! 400: return TRUE;
! 401: }
! 402:
! 403: /*
! 404: <list
! 405: id = ID
! 406: itemType = QName
! 407: {any attributes with non-schema namespace . . .}>
! 408: Content: (annotation?, (simpleType?))
! 409: </list>
! 410: */
! 411: static int schema_list(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr listType, sdlTypePtr cur_type)
! 412: {
! 413: xmlNodePtr trav;
! 414: xmlAttrPtr itemType;
! 415:
! 416: itemType = get_attribute(listType->properties, "itemType");
! 417: if (itemType != NULL) {
! 418: char *type, *ns;
! 419: xmlNsPtr nsptr;
! 420:
! 421: parse_namespace(itemType->children->content, &type, &ns);
! 422: nsptr = xmlSearchNs(listType->doc, listType, BAD_CAST(ns));
! 423: if (nsptr != NULL) {
! 424: sdlTypePtr newType, *tmp;
! 425:
! 426: newType = emalloc(sizeof(sdlType));
! 427: memset(newType, 0, sizeof(sdlType));
! 428:
! 429: newType->name = estrdup(type);
! 430: newType->namens = estrdup((char*)nsptr->href);
! 431:
! 432: newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
! 433:
! 434: if (cur_type->elements == NULL) {
! 435: cur_type->elements = emalloc(sizeof(HashTable));
! 436: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
! 437: }
! 438: zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
! 439: }
! 440: if (type) {efree(type);}
! 441: if (ns) {efree(ns);}
! 442: }
! 443:
! 444: trav = listType->children;
! 445: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 446: /* TODO: <annotation> support */
! 447: trav = trav->next;
! 448: }
! 449: if (trav != NULL && node_is_equal(trav,"simpleType")) {
! 450: sdlTypePtr newType, *tmp;
! 451:
! 452: if (itemType != NULL) {
! 453: soap_error0(E_ERROR, "Parsing Schema: element has both 'itemType' attribute and subtype");
! 454: }
! 455:
! 456: newType = emalloc(sizeof(sdlType));
! 457: memset(newType, 0, sizeof(sdlType));
! 458:
! 459: {
! 460: smart_str anonymous = {0};
! 461:
! 462: smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
! 463: smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
! 464: smart_str_0(&anonymous);
! 465: newType->name = anonymous.c;
! 466: }
! 467: newType->namens = estrdup((char*)tns->children->content);
! 468:
! 469: if (cur_type->elements == NULL) {
! 470: cur_type->elements = emalloc(sizeof(HashTable));
! 471: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
! 472: }
! 473: zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
! 474:
! 475: schema_simpleType(sdl, tns, trav, newType);
! 476:
! 477: trav = trav->next;
! 478: }
! 479: if (trav != NULL) {
! 480: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in list", trav->name);
! 481: }
! 482: return TRUE;
! 483: }
! 484:
! 485: /*
! 486: <union
! 487: id = ID
! 488: memberTypes = List of QName
! 489: {any attributes with non-schema namespace . . .}>
! 490: Content: (annotation?, (simpleType*))
! 491: </union>
! 492: */
! 493: static int schema_union(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr unionType, sdlTypePtr cur_type)
! 494: {
! 495: xmlNodePtr trav;
! 496: xmlAttrPtr memberTypes;
! 497:
! 498: memberTypes = get_attribute(unionType->properties, "memberTypes");
! 499: if (memberTypes != NULL) {
! 500: char *str, *start, *end, *next;
! 501: char *type, *ns;
! 502: xmlNsPtr nsptr;
! 503:
! 504: str = estrdup((char*)memberTypes->children->content);
! 505: whiteSpace_collapse(BAD_CAST(str));
! 506: start = str;
! 507: while (start != NULL && *start != '\0') {
! 508: end = strchr(start,' ');
! 509: if (end == NULL) {
! 510: next = NULL;
! 511: } else {
! 512: *end = '\0';
! 513: next = end+1;
! 514: }
! 515:
! 516: parse_namespace(BAD_CAST(start), &type, &ns);
! 517: nsptr = xmlSearchNs(unionType->doc, unionType, BAD_CAST(ns));
! 518: if (nsptr != NULL) {
! 519: sdlTypePtr newType, *tmp;
! 520:
! 521: newType = emalloc(sizeof(sdlType));
! 522: memset(newType, 0, sizeof(sdlType));
! 523:
! 524: newType->name = estrdup(type);
! 525: newType->namens = estrdup((char*)nsptr->href);
! 526:
! 527: newType->encode = get_create_encoder(sdl, newType, nsptr->href, BAD_CAST(type));
! 528:
! 529: if (cur_type->elements == NULL) {
! 530: cur_type->elements = emalloc(sizeof(HashTable));
! 531: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
! 532: }
! 533: zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
! 534: }
! 535: if (type) {efree(type);}
! 536: if (ns) {efree(ns);}
! 537:
! 538: start = next;
! 539: }
! 540: efree(str);
! 541: }
! 542:
! 543: trav = unionType->children;
! 544: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 545: /* TODO: <annotation> support */
! 546: trav = trav->next;
! 547: }
! 548: while (trav != NULL) {
! 549: if (node_is_equal(trav,"simpleType")) {
! 550: sdlTypePtr newType, *tmp;
! 551:
! 552: newType = emalloc(sizeof(sdlType));
! 553: memset(newType, 0, sizeof(sdlType));
! 554:
! 555: {
! 556: smart_str anonymous = {0};
! 557:
! 558: smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
! 559: smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
! 560: smart_str_0(&anonymous);
! 561: newType->name = anonymous.c;
! 562: }
! 563: newType->namens = estrdup((char*)tns->children->content);
! 564:
! 565: if (cur_type->elements == NULL) {
! 566: cur_type->elements = emalloc(sizeof(HashTable));
! 567: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
! 568: }
! 569: zend_hash_next_index_insert(cur_type->elements, &newType, sizeof(sdlTypePtr), (void **)&tmp);
! 570:
! 571: schema_simpleType(sdl, tns, trav, newType);
! 572:
! 573: } else {
! 574: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
! 575: }
! 576: trav = trav->next;
! 577: }
! 578: if (trav != NULL) {
! 579: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in union", trav->name);
! 580: }
! 581: return TRUE;
! 582: }
! 583:
! 584: /*
! 585: <simpleContent
! 586: id = ID
! 587: {any attributes with non-schema namespace . . .}>
! 588: Content: (annotation?, (restriction | extension))
! 589: </simpleContent>
! 590: */
! 591: static int schema_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr simpCompType, sdlTypePtr cur_type)
! 592: {
! 593: xmlNodePtr trav;
! 594:
! 595: trav = simpCompType->children;
! 596: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 597: /* TODO: <annotation> support */
! 598: trav = trav->next;
! 599: }
! 600: if (trav != NULL) {
! 601: if (node_is_equal(trav, "restriction")) {
! 602: cur_type->kind = XSD_TYPEKIND_RESTRICTION;
! 603: schema_restriction_simpleContent(sdl, tns, trav, cur_type, 0);
! 604: trav = trav->next;
! 605: } else if (node_is_equal(trav, "extension")) {
! 606: cur_type->kind = XSD_TYPEKIND_EXTENSION;
! 607: schema_extension_simpleContent(sdl, tns, trav, cur_type);
! 608: trav = trav->next;
! 609: } else {
! 610: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
! 611: }
! 612: } else {
! 613: soap_error0(E_ERROR, "Parsing Schema: expected <restriction> or <extension> in simpleContent");
! 614: }
! 615: if (trav != NULL) {
! 616: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in simpleContent", trav->name);
! 617: }
! 618:
! 619: return TRUE;
! 620: }
! 621:
! 622: /*
! 623: simpleType:<restriction
! 624: base = QName
! 625: id = ID
! 626: {any attributes with non-schema namespace . . .}>
! 627: Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?)
! 628: </restriction>
! 629: simpleContent:<restriction
! 630: base = QName
! 631: id = ID
! 632: {any attributes with non-schema namespace . . .}>
! 633: Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))
! 634: </restriction>
! 635: */
! 636: static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type, int simpleType)
! 637: {
! 638: xmlNodePtr trav;
! 639: xmlAttrPtr base;
! 640:
! 641: base = get_attribute(restType->properties, "base");
! 642: if (base != NULL) {
! 643: char *type, *ns;
! 644: xmlNsPtr nsptr;
! 645:
! 646: parse_namespace(base->children->content, &type, &ns);
! 647: nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
! 648: if (nsptr != NULL) {
! 649: cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
! 650: }
! 651: if (type) {efree(type);}
! 652: if (ns) {efree(ns);}
! 653: } else if (!simpleType) {
! 654: soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
! 655: }
! 656:
! 657: if (cur_type->restrictions == NULL) {
! 658: cur_type->restrictions = emalloc(sizeof(sdlRestrictions));
! 659: memset(cur_type->restrictions, 0, sizeof(sdlRestrictions));
! 660: }
! 661:
! 662: trav = restType->children;
! 663: if (trav != NULL && node_is_equal(trav, "annotation")) {
! 664: /* TODO: <annotation> support */
! 665: trav = trav->next;
! 666: }
! 667: if (trav != NULL && node_is_equal(trav, "simpleType")) {
! 668: schema_simpleType(sdl, tns, trav, cur_type);
! 669: trav = trav->next;
! 670: }
! 671: while (trav != NULL) {
! 672: if (node_is_equal(trav, "minExclusive")) {
! 673: schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive);
! 674: } else if (node_is_equal(trav, "minInclusive")) {
! 675: schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive);
! 676: } else if (node_is_equal(trav, "maxExclusive")) {
! 677: schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive);
! 678: } else if (node_is_equal(trav, "maxInclusive")) {
! 679: schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive);
! 680: } else if (node_is_equal(trav, "totalDigits")) {
! 681: schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits);
! 682: } else if (node_is_equal(trav, "fractionDigits")) {
! 683: schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits);
! 684: } else if (node_is_equal(trav, "length")) {
! 685: schema_restriction_var_int(trav, &cur_type->restrictions->length);
! 686: } else if (node_is_equal(trav, "minLength")) {
! 687: schema_restriction_var_int(trav, &cur_type->restrictions->minLength);
! 688: } else if (node_is_equal(trav, "maxLength")) {
! 689: schema_restriction_var_int(trav, &cur_type->restrictions->maxLength);
! 690: } else if (node_is_equal(trav, "whiteSpace")) {
! 691: schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace);
! 692: } else if (node_is_equal(trav, "pattern")) {
! 693: schema_restriction_var_char(trav, &cur_type->restrictions->pattern);
! 694: } else if (node_is_equal(trav, "enumeration")) {
! 695: sdlRestrictionCharPtr enumval = NULL;
! 696:
! 697: schema_restriction_var_char(trav, &enumval);
! 698: if (cur_type->restrictions->enumeration == NULL) {
! 699: cur_type->restrictions->enumeration = emalloc(sizeof(HashTable));
! 700: zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, 0);
! 701: }
! 702: if (zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL) == FAILURE) {
! 703: delete_restriction_var_char(&enumval);
! 704: }
! 705: } else {
! 706: break;
! 707: }
! 708: trav = trav->next;
! 709: }
! 710: if (!simpleType) {
! 711: while (trav != NULL) {
! 712: if (node_is_equal(trav,"attribute")) {
! 713: schema_attribute(sdl, tns, trav, cur_type, NULL);
! 714: } else if (node_is_equal(trav,"attributeGroup")) {
! 715: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
! 716: } else if (node_is_equal(trav,"anyAttribute")) {
! 717: /* TODO: <anyAttribute> support */
! 718: trav = trav->next;
! 719: break;
! 720: } else {
! 721: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
! 722: }
! 723: trav = trav->next;
! 724: }
! 725: }
! 726: if (trav != NULL) {
! 727: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
! 728: }
! 729:
! 730: return TRUE;
! 731: }
! 732:
! 733: /*
! 734: <restriction
! 735: base = QName
! 736: id = ID
! 737: {any attributes with non-schema namespace . . .}>
! 738: Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
! 739: </restriction>
! 740: */
! 741: static int schema_restriction_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr restType, sdlTypePtr cur_type)
! 742: {
! 743: xmlAttrPtr base;
! 744: xmlNodePtr trav;
! 745:
! 746: base = get_attribute(restType->properties, "base");
! 747: if (base != NULL) {
! 748: char *type, *ns;
! 749: xmlNsPtr nsptr;
! 750:
! 751: parse_namespace(base->children->content, &type, &ns);
! 752: nsptr = xmlSearchNs(restType->doc, restType, BAD_CAST(ns));
! 753: if (nsptr != NULL) {
! 754: cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
! 755: }
! 756: if (type) {efree(type);}
! 757: if (ns) {efree(ns);}
! 758: } else {
! 759: soap_error0(E_ERROR, "Parsing Schema: restriction has no 'base' attribute");
! 760: }
! 761:
! 762: trav = restType->children;
! 763: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 764: /* TODO: <annotation> support */
! 765: trav = trav->next;
! 766: }
! 767: if (trav != NULL) {
! 768: if (node_is_equal(trav,"group")) {
! 769: schema_group(sdl, tns, trav, cur_type, NULL);
! 770: trav = trav->next;
! 771: } else if (node_is_equal(trav,"all")) {
! 772: schema_all(sdl, tns, trav, cur_type, NULL);
! 773: trav = trav->next;
! 774: } else if (node_is_equal(trav,"choice")) {
! 775: schema_choice(sdl, tns, trav, cur_type, NULL);
! 776: trav = trav->next;
! 777: } else if (node_is_equal(trav,"sequence")) {
! 778: schema_sequence(sdl, tns, trav, cur_type, NULL);
! 779: trav = trav->next;
! 780: }
! 781: }
! 782: while (trav != NULL) {
! 783: if (node_is_equal(trav,"attribute")) {
! 784: schema_attribute(sdl, tns, trav, cur_type, NULL);
! 785: } else if (node_is_equal(trav,"attributeGroup")) {
! 786: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
! 787: } else if (node_is_equal(trav,"anyAttribute")) {
! 788: /* TODO: <anyAttribute> support */
! 789: trav = trav->next;
! 790: break;
! 791: } else {
! 792: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
! 793: }
! 794: trav = trav->next;
! 795: }
! 796: if (trav != NULL) {
! 797: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in restriction", trav->name);
! 798: }
! 799:
! 800: return TRUE;
! 801: }
! 802:
! 803: static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr)
! 804: {
! 805: xmlAttrPtr fixed, value;
! 806:
! 807: if ((*valptr) == NULL) {
! 808: (*valptr) = emalloc(sizeof(sdlRestrictionInt));
! 809: }
! 810: memset((*valptr), 0, sizeof(sdlRestrictionInt));
! 811:
! 812: fixed = get_attribute(val->properties, "fixed");
! 813: (*valptr)->fixed = FALSE;
! 814: if (fixed != NULL) {
! 815: if (!strncmp((char*)fixed->children->content, "true", sizeof("true")) ||
! 816: !strncmp((char*)fixed->children->content, "1", sizeof("1")))
! 817: (*valptr)->fixed = TRUE;
! 818: }
! 819:
! 820: value = get_attribute(val->properties, "value");
! 821: if (value == NULL) {
! 822: soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
! 823: }
! 824:
! 825: (*valptr)->value = atoi((char*)value->children->content);
! 826:
! 827: return TRUE;
! 828: }
! 829:
! 830: static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr)
! 831: {
! 832: xmlAttrPtr fixed, value;
! 833:
! 834: if ((*valptr) == NULL) {
! 835: (*valptr) = emalloc(sizeof(sdlRestrictionChar));
! 836: }
! 837: memset((*valptr), 0, sizeof(sdlRestrictionChar));
! 838:
! 839: fixed = get_attribute(val->properties, "fixed");
! 840: (*valptr)->fixed = FALSE;
! 841: if (fixed != NULL) {
! 842: if (!strncmp((char*)fixed->children->content, "true", sizeof("true")) ||
! 843: !strncmp((char*)fixed->children->content, "1", sizeof("1"))) {
! 844: (*valptr)->fixed = TRUE;
! 845: }
! 846: }
! 847:
! 848: value = get_attribute(val->properties, "value");
! 849: if (value == NULL) {
! 850: soap_error0(E_ERROR, "Parsing Schema: missing restriction value");
! 851: }
! 852:
! 853: (*valptr)->value = estrdup((char*)value->children->content);
! 854: return TRUE;
! 855: }
! 856:
! 857: /*
! 858: From simpleContent (not supported):
! 859: <extension
! 860: base = QName
! 861: id = ID
! 862: {any attributes with non-schema namespace . . .}>
! 863: Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
! 864: </extension>
! 865: */
! 866: static int schema_extension_simpleContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
! 867: {
! 868: xmlNodePtr trav;
! 869: xmlAttrPtr base;
! 870:
! 871: base = get_attribute(extType->properties, "base");
! 872: if (base != NULL) {
! 873: char *type, *ns;
! 874: xmlNsPtr nsptr;
! 875:
! 876: parse_namespace(base->children->content, &type, &ns);
! 877: nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
! 878: if (nsptr != NULL) {
! 879: cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
! 880: }
! 881: if (type) {efree(type);}
! 882: if (ns) {efree(ns);}
! 883: } else {
! 884: soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
! 885: }
! 886:
! 887: trav = extType->children;
! 888: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 889: /* TODO: <annotation> support */
! 890: trav = trav->next;
! 891: }
! 892: while (trav != NULL) {
! 893: if (node_is_equal(trav,"attribute")) {
! 894: schema_attribute(sdl, tns, trav, cur_type, NULL);
! 895: } else if (node_is_equal(trav,"attributeGroup")) {
! 896: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
! 897: } else if (node_is_equal(trav,"anyAttribute")) {
! 898: /* TODO: <anyAttribute> support */
! 899: trav = trav->next;
! 900: break;
! 901: } else {
! 902: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
! 903: }
! 904: trav = trav->next;
! 905: }
! 906: if (trav != NULL) {
! 907: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
! 908: }
! 909: return TRUE;
! 910: }
! 911:
! 912: /*
! 913: From complexContent:
! 914: <extension
! 915: base = QName
! 916: id = ID
! 917: {any attributes with non-schema namespace . . .}>
! 918: Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
! 919: </extension>
! 920: */
! 921: static int schema_extension_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr extType, sdlTypePtr cur_type)
! 922: {
! 923: xmlNodePtr trav;
! 924: xmlAttrPtr base;
! 925:
! 926: base = get_attribute(extType->properties, "base");
! 927: if (base != NULL) {
! 928: char *type, *ns;
! 929: xmlNsPtr nsptr;
! 930:
! 931: parse_namespace(base->children->content, &type, &ns);
! 932: nsptr = xmlSearchNs(extType->doc, extType, BAD_CAST(ns));
! 933: if (nsptr != NULL) {
! 934: cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(type));
! 935: }
! 936: if (type) {efree(type);}
! 937: if (ns) {efree(ns);}
! 938: } else {
! 939: soap_error0(E_ERROR, "Parsing Schema: extension has no 'base' attribute");
! 940: }
! 941:
! 942: trav = extType->children;
! 943: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 944: /* TODO: <annotation> support */
! 945: trav = trav->next;
! 946: }
! 947: if (trav != NULL) {
! 948: if (node_is_equal(trav,"group")) {
! 949: schema_group(sdl, tns, trav, cur_type, NULL);
! 950: trav = trav->next;
! 951: } else if (node_is_equal(trav,"all")) {
! 952: schema_all(sdl, tns, trav, cur_type, NULL);
! 953: trav = trav->next;
! 954: } else if (node_is_equal(trav,"choice")) {
! 955: schema_choice(sdl, tns, trav, cur_type, NULL);
! 956: trav = trav->next;
! 957: } else if (node_is_equal(trav,"sequence")) {
! 958: schema_sequence(sdl, tns, trav, cur_type, NULL);
! 959: trav = trav->next;
! 960: }
! 961: }
! 962: while (trav != NULL) {
! 963: if (node_is_equal(trav,"attribute")) {
! 964: schema_attribute(sdl, tns, trav, cur_type, NULL);
! 965: } else if (node_is_equal(trav,"attributeGroup")) {
! 966: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
! 967: } else if (node_is_equal(trav,"anyAttribute")) {
! 968: /* TODO: <anyAttribute> support */
! 969: trav = trav->next;
! 970: break;
! 971: } else {
! 972: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
! 973: }
! 974: trav = trav->next;
! 975: }
! 976: if (trav != NULL) {
! 977: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in extension", trav->name);
! 978: }
! 979: return TRUE;
! 980: }
! 981:
! 982: void schema_min_max(xmlNodePtr node, sdlContentModelPtr model)
! 983: {
! 984: xmlAttrPtr attr = get_attribute(node->properties, "minOccurs");
! 985:
! 986: if (attr) {
! 987: model->min_occurs = atoi((char*)attr->children->content);
! 988: } else {
! 989: model->min_occurs = 1;
! 990: }
! 991:
! 992: attr = get_attribute(node->properties, "maxOccurs");
! 993: if (attr) {
! 994: if (!strncmp((char*)attr->children->content, "unbounded", sizeof("unbounded"))) {
! 995: model->max_occurs = -1;
! 996: } else {
! 997: model->max_occurs = atoi((char*)attr->children->content);
! 998: }
! 999: } else {
! 1000: model->max_occurs = 1;
! 1001: }
! 1002: }
! 1003:
! 1004: /*
! 1005: <all
! 1006: id = ID
! 1007: maxOccurs = 1 : 1
! 1008: minOccurs = (0 | 1) : 1
! 1009: {any attributes with non-schema namespace . . .}>
! 1010: Content: (annotation?, element*)
! 1011: </all>
! 1012: */
! 1013: static int schema_all(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr all, sdlTypePtr cur_type, sdlContentModelPtr model)
! 1014: {
! 1015: xmlNodePtr trav;
! 1016: sdlContentModelPtr newModel;
! 1017:
! 1018: newModel = emalloc(sizeof(sdlContentModel));
! 1019: newModel->kind = XSD_CONTENT_ALL;
! 1020: newModel->u.content = emalloc(sizeof(HashTable));
! 1021: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
! 1022: if (model == NULL) {
! 1023: cur_type->model = newModel;
! 1024: } else {
! 1025: zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
! 1026: }
! 1027:
! 1028: schema_min_max(all, newModel);
! 1029:
! 1030: trav = all->children;
! 1031: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 1032: /* TODO: <annotation> support */
! 1033: trav = trav->next;
! 1034: }
! 1035: while (trav != NULL) {
! 1036: if (node_is_equal(trav,"element")) {
! 1037: schema_element(sdl, tns, trav, cur_type, newModel);
! 1038: } else {
! 1039: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in all", trav->name);
! 1040: }
! 1041: trav = trav->next;
! 1042: }
! 1043: return TRUE;
! 1044: }
! 1045:
! 1046: /*
! 1047: <group
! 1048: name = NCName
! 1049: Content: (annotation?, (all | choice | sequence))
! 1050: </group>
! 1051: <group
! 1052: name = NCName
! 1053: ref = QName>
! 1054: Content: (annotation?)
! 1055: </group>
! 1056: */
! 1057: static int schema_group(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr groupType, sdlTypePtr cur_type, sdlContentModelPtr model)
! 1058: {
! 1059: xmlNodePtr trav;
! 1060: xmlAttrPtr ns, name, ref = NULL;
! 1061: sdlContentModelPtr newModel;
! 1062:
! 1063: ns = get_attribute(groupType->properties, "targetNamespace");
! 1064: if (ns == NULL) {
! 1065: ns = tns;
! 1066: }
! 1067:
! 1068: name = get_attribute(groupType->properties, "name");
! 1069: if (name == NULL) {
! 1070: name = ref = get_attribute(groupType->properties, "ref");
! 1071: }
! 1072:
! 1073: if (name) {
! 1074: smart_str key = {0};
! 1075:
! 1076: if (ref) {
! 1077: char *type, *ns;
! 1078: xmlNsPtr nsptr;
! 1079:
! 1080: parse_namespace(ref->children->content, &type, &ns);
! 1081: nsptr = xmlSearchNs(groupType->doc, groupType, BAD_CAST(ns));
! 1082: if (nsptr != NULL) {
! 1083: smart_str_appends(&key, (char*)nsptr->href);
! 1084: }
! 1085: smart_str_appendc(&key, ':');
! 1086: smart_str_appends(&key, type);
! 1087: smart_str_0(&key);
! 1088:
! 1089: newModel = emalloc(sizeof(sdlContentModel));
! 1090: newModel->kind = XSD_CONTENT_GROUP_REF;
! 1091: newModel->u.group_ref = estrdup(key.c);
! 1092:
! 1093: if (type) {efree(type);}
! 1094: if (ns) {efree(ns);}
! 1095: } else {
! 1096: newModel = emalloc(sizeof(sdlContentModel));
! 1097: newModel->kind = XSD_CONTENT_SEQUENCE; /* will be redefined */
! 1098: newModel->u.content = emalloc(sizeof(HashTable));
! 1099: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
! 1100:
! 1101: smart_str_appends(&key, (char*)ns->children->content);
! 1102: smart_str_appendc(&key, ':');
! 1103: smart_str_appends(&key, (char*)name->children->content);
! 1104: smart_str_0(&key);
! 1105: }
! 1106:
! 1107: if (cur_type == NULL) {
! 1108: sdlTypePtr newType;
! 1109:
! 1110: newType = emalloc(sizeof(sdlType));
! 1111: memset(newType, 0, sizeof(sdlType));
! 1112:
! 1113: if (sdl->groups == NULL) {
! 1114: sdl->groups = emalloc(sizeof(HashTable));
! 1115: zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
! 1116: }
! 1117: if (zend_hash_add(sdl->groups, key.c, key.len+1, (void**)&newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
! 1118: soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.c);
! 1119: }
! 1120:
! 1121: cur_type = newType;
! 1122: }
! 1123: smart_str_free(&key);
! 1124:
! 1125: if (model == NULL) {
! 1126: cur_type->model = newModel;
! 1127: } else {
! 1128: zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
! 1129: }
! 1130: } else {
! 1131: soap_error0(E_ERROR, "Parsing Schema: group has no 'name' nor 'ref' attributes");
! 1132: }
! 1133:
! 1134: schema_min_max(groupType, newModel);
! 1135:
! 1136: trav = groupType->children;
! 1137: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 1138: /* TODO: <annotation> support */
! 1139: trav = trav->next;
! 1140: }
! 1141: if (trav != NULL) {
! 1142: if (node_is_equal(trav,"choice")) {
! 1143: if (ref != NULL) {
! 1144: soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
! 1145: }
! 1146: newModel->kind = XSD_CONTENT_CHOICE;
! 1147: schema_choice(sdl, tns, trav, cur_type, newModel);
! 1148: trav = trav->next;
! 1149: } else if (node_is_equal(trav,"sequence")) {
! 1150: if (ref != NULL) {
! 1151: soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
! 1152: }
! 1153: newModel->kind = XSD_CONTENT_SEQUENCE;
! 1154: schema_sequence(sdl, tns, trav, cur_type, newModel);
! 1155: trav = trav->next;
! 1156: } else if (node_is_equal(trav,"all")) {
! 1157: if (ref != NULL) {
! 1158: soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
! 1159: }
! 1160: newModel->kind = XSD_CONTENT_ALL;
! 1161: schema_all(sdl, tns, trav, cur_type, newModel);
! 1162: trav = trav->next;
! 1163: } else {
! 1164: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
! 1165: }
! 1166: }
! 1167: if (trav != NULL) {
! 1168: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
! 1169: }
! 1170: return TRUE;
! 1171: }
! 1172: /*
! 1173: <choice
! 1174: id = ID
! 1175: maxOccurs = (nonNegativeInteger | unbounded) : 1
! 1176: minOccurs = nonNegativeInteger : 1
! 1177: {any attributes with non-schema namespace . . .}>
! 1178: Content: (annotation?, (element | group | choice | sequence | any)*)
! 1179: </choice>
! 1180: */
! 1181: static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model)
! 1182: {
! 1183: xmlNodePtr trav;
! 1184: sdlContentModelPtr newModel;
! 1185:
! 1186: newModel = emalloc(sizeof(sdlContentModel));
! 1187: newModel->kind = XSD_CONTENT_CHOICE;
! 1188: newModel->u.content = emalloc(sizeof(HashTable));
! 1189: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
! 1190: if (model == NULL) {
! 1191: cur_type->model = newModel;
! 1192: } else {
! 1193: zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
! 1194: }
! 1195:
! 1196: schema_min_max(choiceType, newModel);
! 1197:
! 1198: trav = choiceType->children;
! 1199: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 1200: /* TODO: <annotation> support */
! 1201: trav = trav->next;
! 1202: }
! 1203: while (trav != NULL) {
! 1204: if (node_is_equal(trav,"element")) {
! 1205: schema_element(sdl, tns, trav, cur_type, newModel);
! 1206: } else if (node_is_equal(trav,"group")) {
! 1207: schema_group(sdl, tns, trav, cur_type, newModel);
! 1208: } else if (node_is_equal(trav,"choice")) {
! 1209: schema_choice(sdl, tns, trav, cur_type, newModel);
! 1210: } else if (node_is_equal(trav,"sequence")) {
! 1211: schema_sequence(sdl, tns, trav, cur_type, newModel);
! 1212: } else if (node_is_equal(trav,"any")) {
! 1213: schema_any(sdl, tns, trav, cur_type, newModel);
! 1214: } else {
! 1215: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in choice", trav->name);
! 1216: }
! 1217: trav = trav->next;
! 1218: }
! 1219: return TRUE;
! 1220: }
! 1221:
! 1222: /*
! 1223: <sequence
! 1224: id = ID
! 1225: maxOccurs = (nonNegativeInteger | unbounded) : 1
! 1226: minOccurs = nonNegativeInteger : 1
! 1227: {any attributes with non-schema namespace . . .}>
! 1228: Content: (annotation?, (element | group | choice | sequence | any)*)
! 1229: </sequence>
! 1230: */
! 1231: static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model)
! 1232: {
! 1233: xmlNodePtr trav;
! 1234: sdlContentModelPtr newModel;
! 1235:
! 1236: newModel = emalloc(sizeof(sdlContentModel));
! 1237: newModel->kind = XSD_CONTENT_SEQUENCE;
! 1238: newModel->u.content = emalloc(sizeof(HashTable));
! 1239: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
! 1240: if (model == NULL) {
! 1241: cur_type->model = newModel;
! 1242: } else {
! 1243: zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
! 1244: }
! 1245:
! 1246: schema_min_max(seqType, newModel);
! 1247:
! 1248: trav = seqType->children;
! 1249: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 1250: /* TODO: <annotation> support */
! 1251: trav = trav->next;
! 1252: }
! 1253: while (trav != NULL) {
! 1254: if (node_is_equal(trav,"element")) {
! 1255: schema_element(sdl, tns, trav, cur_type, newModel);
! 1256: } else if (node_is_equal(trav,"group")) {
! 1257: schema_group(sdl, tns, trav, cur_type, newModel);
! 1258: } else if (node_is_equal(trav,"choice")) {
! 1259: schema_choice(sdl, tns, trav, cur_type, newModel);
! 1260: } else if (node_is_equal(trav,"sequence")) {
! 1261: schema_sequence(sdl, tns, trav, cur_type, newModel);
! 1262: } else if (node_is_equal(trav,"any")) {
! 1263: schema_any(sdl, tns, trav, cur_type, newModel);
! 1264: } else {
! 1265: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in sequence", trav->name);
! 1266: }
! 1267: trav = trav->next;
! 1268: }
! 1269: return TRUE;
! 1270: }
! 1271:
! 1272: /*
! 1273: <any
! 1274: id = ID
! 1275: maxOccurs = (nonNegativeInteger | unbounded) : 1
! 1276: minOccurs = nonNegativeInteger : 1
! 1277: namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any
! 1278: processContents = (lax | skip | strict) : strict
! 1279: {any attributes with non-schema namespace . . .}>
! 1280: Content: (annotation?)
! 1281: </any>
! 1282: */
! 1283: static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr cur_type, sdlContentModelPtr model)
! 1284: {
! 1285: if (model != NULL) {
! 1286: sdlContentModelPtr newModel;
! 1287:
! 1288: newModel = emalloc(sizeof(sdlContentModel));
! 1289: newModel->kind = XSD_CONTENT_ANY;
! 1290:
! 1291: schema_min_max(anyType, newModel);
! 1292:
! 1293: zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
! 1294: }
! 1295: return TRUE;
! 1296: }
! 1297:
! 1298: /*
! 1299: <complexContent
! 1300: id = ID
! 1301: mixed = boolean
! 1302: {any attributes with non-schema namespace . . .}>
! 1303: Content: (annotation?, (restriction | extension))
! 1304: </complexContent>
! 1305: */
! 1306: static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont, sdlTypePtr cur_type)
! 1307: {
! 1308: xmlNodePtr trav;
! 1309:
! 1310: trav = compCont->children;
! 1311: if (trav != NULL && node_is_equal(trav,"annotation")) {
! 1312: /* TODO: <annotation> support */
! 1313: trav = trav->next;
! 1314: }
! 1315: if (trav != NULL) {
! 1316: if (node_is_equal(trav, "restriction")) {
! 1317: cur_type->kind = XSD_TYPEKIND_RESTRICTION;
! 1318: schema_restriction_complexContent(sdl, tns, trav, cur_type);
! 1319: trav = trav->next;
! 1320: } else if (node_is_equal(trav, "extension")) {
! 1321: cur_type->kind = XSD_TYPEKIND_EXTENSION;
! 1322: schema_extension_complexContent(sdl, tns, trav, cur_type);
! 1323: trav = trav->next;
! 1324: } else {
! 1325: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
! 1326: }
! 1327: } else {
! 1328: soap_error0(E_ERROR, "Parsing Schema: <restriction> or <extension> expected in complexContent");
! 1329: }
! 1330: if (trav != NULL) {
! 1331: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
! 1332: }
! 1333:
! 1334: return TRUE;
! 1335: }
! 1336:
! 1337: /*
! 1338: <complexType
! 1339: abstract = boolean : false
! 1340: block = (#all | List of (extension | restriction))
! 1341: final = (#all | List of (extension | restriction))
! 1342: id = ID
! 1343: mixed = boolean : false
! 1344: name = NCName
! 1345: {any attributes with non-schema namespace . . .}>
! 1346: Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
! 1347: </complexType>
! 1348: */
! 1349: static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type)
! 1350: {
! 1351: xmlNodePtr trav;
! 1352: xmlAttrPtr attrs, name, ns;
! 1353:
! 1354: attrs = compType->properties;
! 1355: ns = get_attribute(attrs, "targetNamespace");
! 1356: if (ns == NULL) {
! 1357: ns = tns;
! 1358: }
! 1359:
! 1360: name = get_attribute(attrs, "name");
! 1361: if (cur_type != NULL) {
! 1362: /* Anonymous type inside <element> */
! 1363: sdlTypePtr newType, *ptr;
! 1364:
! 1365: newType = emalloc(sizeof(sdlType));
! 1366: memset(newType, 0, sizeof(sdlType));
! 1367: newType->kind = XSD_TYPEKIND_COMPLEX;
! 1368: if (name != NULL) {
! 1369: newType->name = estrdup((char*)name->children->content);
! 1370: newType->namens = estrdup((char*)ns->children->content);
! 1371: } else {
! 1372: newType->name = estrdup(cur_type->name);
! 1373: newType->namens = estrdup(cur_type->namens);
! 1374: }
! 1375:
! 1376: zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
! 1377:
! 1378: if (sdl->encoders == NULL) {
! 1379: sdl->encoders = emalloc(sizeof(HashTable));
! 1380: zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
! 1381: }
! 1382: cur_type->encode = emalloc(sizeof(encode));
! 1383: memset(cur_type->encode, 0, sizeof(encode));
! 1384: cur_type->encode->details.ns = estrdup(newType->namens);
! 1385: cur_type->encode->details.type_str = estrdup(newType->name);
! 1386: cur_type->encode->details.sdl_type = *ptr;
! 1387: cur_type->encode->to_xml = sdl_guess_convert_xml;
! 1388: cur_type->encode->to_zval = sdl_guess_convert_zval;
! 1389: zend_hash_next_index_insert(sdl->encoders, &cur_type->encode, sizeof(encodePtr), NULL);
! 1390:
! 1391: cur_type =*ptr;
! 1392:
! 1393: } else if (name) {
! 1394: sdlTypePtr newType, *ptr;
! 1395:
! 1396: newType = emalloc(sizeof(sdlType));
! 1397: memset(newType, 0, sizeof(sdlType));
! 1398: newType->kind = XSD_TYPEKIND_COMPLEX;
! 1399: newType->name = estrdup((char*)name->children->content);
! 1400: newType->namens = estrdup((char*)ns->children->content);
! 1401:
! 1402: zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
! 1403:
! 1404: cur_type = (*ptr);
! 1405: create_encoder(sdl, cur_type, ns->children->content, name->children->content);
! 1406: } else {
! 1407: soap_error0(E_ERROR, "Parsing Schema: complexType has no 'name' attribute");
! 1408: return FALSE;
! 1409: }
! 1410:
! 1411: trav = compType->children;
! 1412: if (trav != NULL && node_is_equal(trav, "annotation")) {
! 1413: /* TODO: <annotation> support */
! 1414: trav = trav->next;
! 1415: }
! 1416: if (trav != NULL) {
! 1417: if (node_is_equal(trav,"simpleContent")) {
! 1418: schema_simpleContent(sdl, tns, trav, cur_type);
! 1419: trav = trav->next;
! 1420: } else if (node_is_equal(trav,"complexContent")) {
! 1421: schema_complexContent(sdl, tns, trav, cur_type);
! 1422: trav = trav->next;
! 1423: } else {
! 1424: if (node_is_equal(trav,"group")) {
! 1425: schema_group(sdl, tns, trav, cur_type, NULL);
! 1426: trav = trav->next;
! 1427: } else if (node_is_equal(trav,"all")) {
! 1428: schema_all(sdl, tns, trav, cur_type, NULL);
! 1429: trav = trav->next;
! 1430: } else if (node_is_equal(trav,"choice")) {
! 1431: schema_choice(sdl, tns, trav, cur_type, NULL);
! 1432: trav = trav->next;
! 1433: } else if (node_is_equal(trav,"sequence")) {
! 1434: schema_sequence(sdl, tns, trav, cur_type, NULL);
! 1435: trav = trav->next;
! 1436: }
! 1437: while (trav != NULL) {
! 1438: if (node_is_equal(trav,"attribute")) {
! 1439: schema_attribute(sdl, tns, trav, cur_type, NULL);
! 1440: } else if (node_is_equal(trav,"attributeGroup")) {
! 1441: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
! 1442: } else if (node_is_equal(trav,"anyAttribute")) {
! 1443: /* TODO: <anyAttribute> support */
! 1444: trav = trav->next;
! 1445: break;
! 1446: } else {
! 1447: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
! 1448: }
! 1449: trav = trav->next;
! 1450: }
! 1451: }
! 1452: }
! 1453: if (trav != NULL) {
! 1454: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
! 1455: }
! 1456: return TRUE;
! 1457: }
! 1458: /*
! 1459: <element
! 1460: abstract = boolean : false
! 1461: block = (#all | List of (extension | restriction | substitution))
! 1462: default = string
! 1463: final = (#all | List of (extension | restriction))
! 1464: fixed = string
! 1465: form = (qualified | unqualified)
! 1466: id = ID
! 1467: maxOccurs = (nonNegativeInteger | unbounded) : 1
! 1468: minOccurs = nonNegativeInteger : 1
! 1469: name = NCName
! 1470: nillable = boolean : false
! 1471: ref = QName
! 1472: substitutionGroup = QName
! 1473: type = QName
! 1474: {any attributes with non-schema namespace . . .}>
! 1475: Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
! 1476: </element>
! 1477: */
! 1478: static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model)
! 1479: {
! 1480: xmlNodePtr trav;
! 1481: xmlAttrPtr attrs, attr, ns, name, type, ref = NULL;
! 1482:
! 1483: attrs = element->properties;
! 1484: ns = get_attribute(attrs, "targetNamespace");
! 1485: if (ns == NULL) {
! 1486: ns = tns;
! 1487: }
! 1488:
! 1489: name = get_attribute(attrs, "name");
! 1490: if (name == NULL) {
! 1491: name = ref = get_attribute(attrs, "ref");
! 1492: }
! 1493:
! 1494: if (name) {
! 1495: HashTable *addHash;
! 1496: sdlTypePtr newType;
! 1497: smart_str key = {0};
! 1498:
! 1499: newType = emalloc(sizeof(sdlType));
! 1500: memset(newType, 0, sizeof(sdlType));
! 1501:
! 1502: if (ref) {
! 1503: smart_str nscat = {0};
! 1504: char *type, *ns;
! 1505: xmlNsPtr nsptr;
! 1506:
! 1507: parse_namespace(ref->children->content, &type, &ns);
! 1508: nsptr = xmlSearchNs(element->doc, element, BAD_CAST(ns));
! 1509: if (nsptr != NULL) {
! 1510: smart_str_appends(&nscat, (char*)nsptr->href);
! 1511: newType->namens = estrdup((char*)nsptr->href);
! 1512: }
! 1513: smart_str_appendc(&nscat, ':');
! 1514: smart_str_appends(&nscat, type);
! 1515: newType->name = estrdup(type);
! 1516: smart_str_0(&nscat);
! 1517: if (type) {efree(type);}
! 1518: if (ns) {efree(ns);}
! 1519: newType->ref = estrdup(nscat.c);
! 1520: smart_str_free(&nscat);
! 1521: } else {
! 1522: newType->name = estrdup((char*)name->children->content);
! 1523: newType->namens = estrdup((char*)ns->children->content);
! 1524: }
! 1525:
! 1526: newType->nillable = FALSE;
! 1527:
! 1528: if (cur_type == NULL) {
! 1529: if (sdl->elements == NULL) {
! 1530: sdl->elements = emalloc(sizeof(HashTable));
! 1531: zend_hash_init(sdl->elements, 0, NULL, delete_type, 0);
! 1532: }
! 1533: addHash = sdl->elements;
! 1534: smart_str_appends(&key, newType->namens);
! 1535: smart_str_appendc(&key, ':');
! 1536: smart_str_appends(&key, newType->name);
! 1537: } else {
! 1538: if (cur_type->elements == NULL) {
! 1539: cur_type->elements = emalloc(sizeof(HashTable));
! 1540: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
! 1541: }
! 1542: addHash = cur_type->elements;
! 1543: smart_str_appends(&key, newType->name);
! 1544: }
! 1545:
! 1546: smart_str_0(&key);
! 1547: if (zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
! 1548: if (cur_type == NULL) {
! 1549: soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.c);
! 1550: } else {
! 1551: zend_hash_next_index_insert(addHash, &newType, sizeof(sdlTypePtr), NULL);
! 1552: }
! 1553: }
! 1554: smart_str_free(&key);
! 1555:
! 1556: if (model != NULL) {
! 1557: sdlContentModelPtr newModel = emalloc(sizeof(sdlContentModel));
! 1558:
! 1559: newModel->kind = XSD_CONTENT_ELEMENT;
! 1560: newModel->u.element = newType;
! 1561:
! 1562: schema_min_max(element, newModel);
! 1563:
! 1564:
! 1565: zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
! 1566: }
! 1567: cur_type = newType;
! 1568: } else {
! 1569: soap_error0(E_ERROR, "Parsing Schema: element has no 'name' nor 'ref' attributes");
! 1570: }
! 1571:
! 1572: /* nillable = boolean : false */
! 1573: attrs = element->properties;
! 1574: attr = get_attribute(attrs, "nillable");
! 1575: if (attr) {
! 1576: if (ref != NULL) {
! 1577: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'nillable' attributes");
! 1578: }
! 1579: if (!stricmp((char*)attr->children->content, "true") ||
! 1580: !stricmp((char*)attr->children->content, "1")) {
! 1581: cur_type->nillable = TRUE;
! 1582: } else {
! 1583: cur_type->nillable = FALSE;
! 1584: }
! 1585: } else {
! 1586: cur_type->nillable = FALSE;
! 1587: }
! 1588:
! 1589: attr = get_attribute(attrs, "fixed");
! 1590: if (attr) {
! 1591: if (ref != NULL) {
! 1592: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
! 1593: }
! 1594: cur_type->fixed = estrdup((char*)attr->children->content);
! 1595: }
! 1596:
! 1597: attr = get_attribute(attrs, "default");
! 1598: if (attr) {
! 1599: if (ref != NULL) {
! 1600: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
! 1601: } else if (ref != NULL) {
! 1602: soap_error0(E_ERROR, "Parsing Schema: element has both 'default' and 'fixed' attributes");
! 1603: }
! 1604: cur_type->def = estrdup((char*)attr->children->content);
! 1605: }
! 1606:
! 1607: /* form */
! 1608: attr = get_attribute(attrs, "form");
! 1609: if (attr) {
! 1610: if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
! 1611: cur_type->form = XSD_FORM_QUALIFIED;
! 1612: } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
! 1613: cur_type->form = XSD_FORM_UNQUALIFIED;
! 1614: } else {
! 1615: cur_type->form = XSD_FORM_DEFAULT;
! 1616: }
! 1617: } else {
! 1618: cur_type->form = XSD_FORM_DEFAULT;
! 1619: }
! 1620: if (cur_type->form == XSD_FORM_DEFAULT) {
! 1621: xmlNodePtr parent = element->parent;
! 1622: while (parent) {
! 1623: if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
! 1624: xmlAttrPtr def;
! 1625: def = get_attribute(parent->properties, "elementFormDefault");
! 1626: if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
! 1627: cur_type->form = XSD_FORM_UNQUALIFIED;
! 1628: } else {
! 1629: cur_type->form = XSD_FORM_QUALIFIED;
! 1630: }
! 1631: break;
! 1632: }
! 1633: parent = parent->parent;
! 1634: }
! 1635: if (parent == NULL) {
! 1636: cur_type->form = XSD_FORM_UNQUALIFIED;
! 1637: }
! 1638: }
! 1639:
! 1640: /* type = QName */
! 1641: type = get_attribute(attrs, "type");
! 1642: if (type) {
! 1643: char *cptype, *str_ns;
! 1644: xmlNsPtr nsptr;
! 1645:
! 1646: if (ref != NULL) {
! 1647: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'type' attributes");
! 1648: }
! 1649: parse_namespace(type->children->content, &cptype, &str_ns);
! 1650: nsptr = xmlSearchNs(element->doc, element, BAD_CAST(str_ns));
! 1651: if (nsptr != NULL) {
! 1652: cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
! 1653: }
! 1654: if (str_ns) {efree(str_ns);}
! 1655: if (cptype) {efree(cptype);}
! 1656: }
! 1657:
! 1658: trav = element->children;
! 1659: if (trav != NULL && node_is_equal(trav, "annotation")) {
! 1660: /* TODO: <annotation> support */
! 1661: trav = trav->next;
! 1662: }
! 1663: if (trav != NULL) {
! 1664: if (node_is_equal(trav,"simpleType")) {
! 1665: if (ref != NULL) {
! 1666: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
! 1667: } else if (type != NULL) {
! 1668: soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
! 1669: }
! 1670: schema_simpleType(sdl, tns, trav, cur_type);
! 1671: trav = trav->next;
! 1672: } else if (node_is_equal(trav,"complexType")) {
! 1673: if (ref != NULL) {
! 1674: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
! 1675: } else if (type != NULL) {
! 1676: soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
! 1677: }
! 1678: schema_complexType(sdl, tns, trav, cur_type);
! 1679: trav = trav->next;
! 1680: }
! 1681: }
! 1682: while (trav != NULL) {
! 1683: if (node_is_equal(trav,"unique")) {
! 1684: /* TODO: <unique> support */
! 1685: } else if (node_is_equal(trav,"key")) {
! 1686: /* TODO: <key> support */
! 1687: } else if (node_is_equal(trav,"keyref")) {
! 1688: /* TODO: <keyref> support */
! 1689: } else {
! 1690: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in element", trav->name);
! 1691: }
! 1692: trav = trav->next;
! 1693: }
! 1694:
! 1695: return TRUE;
! 1696: }
! 1697:
! 1698: /*
! 1699: <attribute
! 1700: default = string
! 1701: fixed = string
! 1702: form = (qualified | unqualified)
! 1703: id = ID
! 1704: name = NCName
! 1705: ref = QName
! 1706: type = QName
! 1707: use = (optional | prohibited | required) : optional
! 1708: {any attributes with non-schema namespace . . .}>
! 1709: Content: (annotation?, (simpleType?))
! 1710: </attribute>
! 1711: */
! 1712: static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx)
! 1713: {
! 1714: sdlAttributePtr newAttr;
! 1715: xmlAttrPtr attr, name, ref = NULL, type = NULL;
! 1716: xmlNodePtr trav;
! 1717:
! 1718: name = get_attribute(attrType->properties, "name");
! 1719: if (name == NULL) {
! 1720: name = ref = get_attribute(attrType->properties, "ref");
! 1721: }
! 1722: if (name) {
! 1723: HashTable *addHash;
! 1724: smart_str key = {0};
! 1725:
! 1726: newAttr = emalloc(sizeof(sdlAttribute));
! 1727: memset(newAttr, 0, sizeof(sdlAttribute));
! 1728:
! 1729: if (ref) {
! 1730: char *attr_name, *ns;
! 1731: xmlNsPtr nsptr;
! 1732:
! 1733: parse_namespace(ref->children->content, &attr_name, &ns);
! 1734: nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(ns));
! 1735: if (nsptr != NULL) {
! 1736: smart_str_appends(&key, (char*)nsptr->href);
! 1737: newAttr->namens = estrdup((char*)nsptr->href);
! 1738: }
! 1739: smart_str_appendc(&key, ':');
! 1740: smart_str_appends(&key, attr_name);
! 1741: smart_str_0(&key);
! 1742: newAttr->ref = estrdup(key.c);
! 1743: if (attr_name) {efree(attr_name);}
! 1744: if (ns) {efree(ns);}
! 1745: } else {
! 1746: xmlAttrPtr ns;
! 1747:
! 1748: ns = get_attribute(attrType->properties, "targetNamespace");
! 1749: if (ns == NULL) {
! 1750: ns = tns;
! 1751: }
! 1752: if (ns != NULL) {
! 1753: smart_str_appends(&key, (char*)ns->children->content);
! 1754: smart_str_appendc(&key, ':');
! 1755: newAttr->namens = estrdup((char*)ns->children->content);
! 1756: }
! 1757: smart_str_appends(&key, (char*)name->children->content);
! 1758: smart_str_0(&key);
! 1759: }
! 1760:
! 1761: if (cur_type == NULL) {
! 1762: addHash = ctx->attributes;
! 1763: } else {
! 1764: if (cur_type->attributes == NULL) {
! 1765: cur_type->attributes = emalloc(sizeof(HashTable));
! 1766: zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
! 1767: }
! 1768: addHash = cur_type->attributes;
! 1769: }
! 1770:
! 1771: if (zend_hash_add(addHash, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL) != SUCCESS) {
! 1772: soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.c);
! 1773: }
! 1774: smart_str_free(&key);
! 1775: } else{
! 1776: soap_error0(E_ERROR, "Parsing Schema: attribute has no 'name' nor 'ref' attributes");
! 1777: }
! 1778:
! 1779: /* type = QName */
! 1780: type = get_attribute(attrType->properties, "type");
! 1781: if (type) {
! 1782: char *cptype, *str_ns;
! 1783: xmlNsPtr nsptr;
! 1784:
! 1785: if (ref != NULL) {
! 1786: soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' and 'type' attributes");
! 1787: }
! 1788: parse_namespace(type->children->content, &cptype, &str_ns);
! 1789: nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(str_ns));
! 1790: if (nsptr != NULL) {
! 1791: newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
! 1792: }
! 1793: if (str_ns) {efree(str_ns);}
! 1794: if (cptype) {efree(cptype);}
! 1795: }
! 1796:
! 1797: attr = attrType->properties;
! 1798: while (attr != NULL) {
! 1799: if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) {
! 1800: newAttr->def = estrdup((char*)attr->children->content);
! 1801: } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) {
! 1802: newAttr->fixed = estrdup((char*)attr->children->content);
! 1803: } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) {
! 1804: if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
! 1805: newAttr->form = XSD_FORM_QUALIFIED;
! 1806: } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
! 1807: newAttr->form = XSD_FORM_UNQUALIFIED;
! 1808: } else {
! 1809: newAttr->form = XSD_FORM_DEFAULT;
! 1810: }
! 1811: } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) {
! 1812: /* skip */
! 1813: } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) {
! 1814: newAttr->name = estrdup((char*)attr->children->content);
! 1815: } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) {
! 1816: /* already processed */
! 1817: } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) {
! 1818: /* already processed */
! 1819: } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) {
! 1820: if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) {
! 1821: newAttr->use = XSD_USE_PROHIBITED;
! 1822: } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) {
! 1823: newAttr->use = XSD_USE_REQUIRED;
! 1824: } else if (strncmp((char*)attr->children->content, "optional", sizeof("optional")) == 0) {
! 1825: newAttr->use = XSD_USE_OPTIONAL;
! 1826: } else {
! 1827: newAttr->use = XSD_USE_DEFAULT;
! 1828: }
! 1829: } else {
! 1830: xmlNsPtr nsPtr = attr_find_ns(attr);
! 1831:
! 1832: if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) {
! 1833: smart_str key2 = {0};
! 1834: sdlExtraAttributePtr ext;
! 1835: xmlNsPtr nsptr;
! 1836: char *value, *ns;
! 1837:
! 1838: ext = emalloc(sizeof(sdlExtraAttribute));
! 1839: memset(ext, 0, sizeof(sdlExtraAttribute));
! 1840: parse_namespace(attr->children->content, &value, &ns);
! 1841: nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
! 1842: if (nsptr) {
! 1843: ext->ns = estrdup((char*)nsptr->href);
! 1844: ext->val = estrdup(value);
! 1845: } else {
! 1846: ext->val = estrdup((char*)attr->children->content);
! 1847: }
! 1848: if (ns) {efree(ns);}
! 1849: efree(value);
! 1850:
! 1851: if (!newAttr->extraAttributes) {
! 1852: newAttr->extraAttributes = emalloc(sizeof(HashTable));
! 1853: zend_hash_init(newAttr->extraAttributes, 0, NULL, delete_extra_attribute, 0);
! 1854: }
! 1855:
! 1856: smart_str_appends(&key2, (char*)nsPtr->href);
! 1857: smart_str_appendc(&key2, ':');
! 1858: smart_str_appends(&key2, (char*)attr->name);
! 1859: smart_str_0(&key2);
! 1860: zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
! 1861: smart_str_free(&key2);
! 1862: }
! 1863: }
! 1864: attr = attr->next;
! 1865: }
! 1866: if (newAttr->form == XSD_FORM_DEFAULT) {
! 1867: xmlNodePtr parent = attrType->parent;
! 1868: while (parent) {
! 1869: if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
! 1870: xmlAttrPtr def;
! 1871: def = get_attribute(parent->properties, "attributeFormDefault");
! 1872: if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
! 1873: newAttr->form = XSD_FORM_UNQUALIFIED;
! 1874: } else {
! 1875: newAttr->form = XSD_FORM_QUALIFIED;
! 1876: }
! 1877: break;
! 1878: }
! 1879: parent = parent->parent;
! 1880: }
! 1881: if (parent == NULL) {
! 1882: newAttr->form = XSD_FORM_UNQUALIFIED;
! 1883: }
! 1884: }
! 1885: trav = attrType->children;
! 1886: if (trav != NULL && node_is_equal(trav, "annotation")) {
! 1887: /* TODO: <annotation> support */
! 1888: trav = trav->next;
! 1889: }
! 1890: if (trav != NULL) {
! 1891: if (node_is_equal(trav,"simpleType")) {
! 1892: sdlTypePtr dummy_type;
! 1893: if (ref != NULL) {
! 1894: soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
! 1895: } else if (type != NULL) {
! 1896: soap_error0(E_ERROR, "Parsing Schema: attribute has both 'type' attribute and subtype");
! 1897: }
! 1898: dummy_type = emalloc(sizeof(sdlType));
! 1899: memset(dummy_type, 0, sizeof(sdlType));
! 1900: {
! 1901: smart_str anonymous = {0};
! 1902:
! 1903: smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
! 1904: smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
! 1905: smart_str_0(&anonymous);
! 1906: dummy_type->name = anonymous.c;
! 1907: }
! 1908: dummy_type->namens = estrdup((char*)tns->children->content);
! 1909: schema_simpleType(sdl, tns, trav, dummy_type);
! 1910: newAttr->encode = dummy_type->encode;
! 1911: delete_type(&dummy_type);
! 1912: trav = trav->next;
! 1913: }
! 1914: }
! 1915: if (trav != NULL) {
! 1916: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attribute", trav->name);
! 1917: }
! 1918: return TRUE;
! 1919: }
! 1920:
! 1921: static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGroup, sdlTypePtr cur_type, sdlCtx *ctx)
! 1922: {
! 1923: xmlNodePtr trav;
! 1924: xmlAttrPtr name, ref = NULL;
! 1925:
! 1926:
! 1927: name = get_attribute(attrGroup->properties, "name");
! 1928: if (name == NULL) {
! 1929: name = ref = get_attribute(attrGroup->properties, "ref");
! 1930: }
! 1931: if (name) {
! 1932: if (cur_type == NULL) {
! 1933: xmlAttrPtr ns;
! 1934: sdlTypePtr newType;
! 1935: smart_str key = {0};
! 1936:
! 1937: ns = get_attribute(attrGroup->properties, "targetNamespace");
! 1938: if (ns == NULL) {
! 1939: ns = tns;
! 1940: }
! 1941: newType = emalloc(sizeof(sdlType));
! 1942: memset(newType, 0, sizeof(sdlType));
! 1943: newType->name = estrdup((char*)name->children->content);
! 1944: newType->namens = estrdup((char*)ns->children->content);
! 1945:
! 1946: smart_str_appends(&key, newType->namens);
! 1947: smart_str_appendc(&key, ':');
! 1948: smart_str_appends(&key, newType->name);
! 1949: smart_str_0(&key);
! 1950:
! 1951: if (zend_hash_add(ctx->attributeGroups, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
! 1952: soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.c);
! 1953: }
! 1954: cur_type = newType;
! 1955: smart_str_free(&key);
! 1956: } else if (ref) {
! 1957: sdlAttributePtr newAttr;
! 1958: char *group_name, *ns;
! 1959: smart_str key = {0};
! 1960: xmlNsPtr nsptr;
! 1961:
! 1962: if (cur_type->attributes == NULL) {
! 1963: cur_type->attributes = emalloc(sizeof(HashTable));
! 1964: zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
! 1965: }
! 1966: newAttr = emalloc(sizeof(sdlAttribute));
! 1967: memset(newAttr, 0, sizeof(sdlAttribute));
! 1968:
! 1969: parse_namespace(ref->children->content, &group_name, &ns);
! 1970: nsptr = xmlSearchNs(attrGroup->doc, attrGroup, BAD_CAST(ns));
! 1971: if (nsptr != NULL) {
! 1972: smart_str_appends(&key, (char*)nsptr->href);
! 1973: }
! 1974: smart_str_appendc(&key, ':');
! 1975: smart_str_appends(&key, group_name);
! 1976: smart_str_0(&key);
! 1977: newAttr->ref = estrdup(key.c);
! 1978: if (group_name) {efree(group_name);}
! 1979: if (ns) {efree(ns);}
! 1980: smart_str_free(&key);
! 1981:
! 1982: zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
! 1983: cur_type = NULL;
! 1984: }
! 1985: } else{
! 1986: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has no 'name' nor 'ref' attributes");
! 1987: }
! 1988:
! 1989: trav = attrGroup->children;
! 1990: if (trav != NULL && node_is_equal(trav, "annotation")) {
! 1991: /* TODO: <annotation> support */
! 1992: trav = trav->next;
! 1993: }
! 1994: while (trav != NULL) {
! 1995: if (node_is_equal(trav,"attribute")) {
! 1996: if (ref != NULL) {
! 1997: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
! 1998: }
! 1999: schema_attribute(sdl, tns, trav, cur_type, NULL);
! 2000: } else if (node_is_equal(trav,"attributeGroup")) {
! 2001: if (ref != NULL) {
! 2002: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
! 2003: }
! 2004: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
! 2005: } else if (node_is_equal(trav,"anyAttribute")) {
! 2006: if (ref != NULL) {
! 2007: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
! 2008: }
! 2009: /* TODO: <anyAttribute> support */
! 2010: trav = trav->next;
! 2011: break;
! 2012: } else {
! 2013: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
! 2014: }
! 2015: trav = trav->next;
! 2016: }
! 2017: if (trav != NULL) {
! 2018: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
! 2019: }
! 2020: return TRUE;
! 2021: }
! 2022:
! 2023: static void copy_extra_attribute(void *attribute)
! 2024: {
! 2025: sdlExtraAttributePtr *attr = (sdlExtraAttributePtr*)attribute;
! 2026: sdlExtraAttributePtr new_attr;
! 2027:
! 2028: new_attr = emalloc(sizeof(sdlExtraAttribute));
! 2029: memcpy(new_attr, *attr, sizeof(sdlExtraAttribute));
! 2030: *attr = new_attr;
! 2031: if (new_attr->ns) {
! 2032: new_attr->ns = estrdup(new_attr->ns);
! 2033: }
! 2034: if (new_attr->val) {
! 2035: new_attr->val = estrdup(new_attr->val);
! 2036: }
! 2037: }
! 2038:
! 2039: static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
! 2040: {
! 2041: sdlAttributePtr *tmp;
! 2042:
! 2043: if (attr->ref != NULL) {
! 2044: if (ctx->attributes != NULL) {
! 2045: if (zend_hash_find(ctx->attributes, attr->ref, strlen(attr->ref)+1, (void**)&tmp) == SUCCESS) {
! 2046: schema_attribute_fixup(ctx, *tmp);
! 2047: if ((*tmp)->name != NULL && attr->name == NULL) {
! 2048: attr->name = estrdup((*tmp)->name);
! 2049: }
! 2050: if ((*tmp)->namens != NULL && attr->namens == NULL) {
! 2051: attr->namens = estrdup((*tmp)->namens);
! 2052: }
! 2053: if ((*tmp)->def != NULL && attr->def == NULL) {
! 2054: attr->def = estrdup((*tmp)->def);
! 2055: }
! 2056: if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
! 2057: attr->fixed = estrdup((*tmp)->fixed);
! 2058: }
! 2059: if (attr->form == XSD_FORM_DEFAULT) {
! 2060: attr->form = (*tmp)->form;
! 2061: }
! 2062: if (attr->use == XSD_USE_DEFAULT) {
! 2063: attr->use = (*tmp)->use;
! 2064: }
! 2065: if ((*tmp)->extraAttributes != NULL) {
! 2066: xmlNodePtr node;
! 2067:
! 2068: attr->extraAttributes = emalloc(sizeof(HashTable));
! 2069: zend_hash_init(attr->extraAttributes, zend_hash_num_elements((*tmp)->extraAttributes), NULL, delete_extra_attribute, 0);
! 2070: zend_hash_copy(attr->extraAttributes, (*tmp)->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
! 2071: }
! 2072: attr->encode = (*tmp)->encode;
! 2073: }
! 2074: }
! 2075: if (attr->name == NULL && attr->ref != NULL) {
! 2076: char *name = strrchr(attr->ref, ':');
! 2077: if (name) {
! 2078: attr->name = estrdup(name+1);
! 2079: } else{
! 2080: attr->name = estrdup(attr->ref);
! 2081: }
! 2082: }
! 2083: efree(attr->ref);
! 2084: attr->ref = NULL;
! 2085: }
! 2086: }
! 2087:
! 2088: static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
! 2089: {
! 2090: sdlTypePtr *tmp;
! 2091: sdlAttributePtr *tmp_attr;
! 2092:
! 2093: if (attr->ref != NULL) {
! 2094: if (ctx->attributeGroups != NULL) {
! 2095: if (zend_hash_find(ctx->attributeGroups, attr->ref, strlen(attr->ref)+1, (void**)&tmp) == SUCCESS) {
! 2096: if ((*tmp)->attributes) {
! 2097: zend_hash_internal_pointer_reset((*tmp)->attributes);
! 2098: while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
! 2099: if (zend_hash_get_current_key_type((*tmp)->attributes) == HASH_KEY_IS_STRING) {
! 2100: char* key;
! 2101: uint key_len;
! 2102: sdlAttributePtr newAttr;
! 2103:
! 2104: schema_attribute_fixup(ctx,*tmp_attr);
! 2105:
! 2106: newAttr = emalloc(sizeof(sdlAttribute));
! 2107: memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
! 2108: if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
! 2109: if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
! 2110: if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
! 2111: if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
! 2112: if (newAttr->extraAttributes) {
! 2113: xmlNodePtr node;
! 2114: HashTable *ht = emalloc(sizeof(HashTable));
! 2115: zend_hash_init(ht, zend_hash_num_elements(newAttr->extraAttributes), NULL, delete_extra_attribute, 0);
! 2116: zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
! 2117: newAttr->extraAttributes = ht;
! 2118: }
! 2119:
! 2120: zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
! 2121: zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
! 2122:
! 2123: zend_hash_move_forward((*tmp)->attributes);
! 2124: } else {
! 2125: ulong index;
! 2126:
! 2127: schema_attributegroup_fixup(ctx,*tmp_attr, ht);
! 2128: zend_hash_get_current_key((*tmp)->attributes, NULL, &index, 0);
! 2129: zend_hash_index_del((*tmp)->attributes, index);
! 2130: }
! 2131: }
! 2132: }
! 2133: }
! 2134: }
! 2135: efree(attr->ref);
! 2136: attr->ref = NULL;
! 2137: }
! 2138: }
! 2139:
! 2140: static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
! 2141: {
! 2142: switch (model->kind) {
! 2143: case XSD_CONTENT_GROUP_REF: {
! 2144: sdlTypePtr *tmp;
! 2145:
! 2146: if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
! 2147: schema_type_fixup(ctx,*tmp);
! 2148: efree(model->u.group_ref);
! 2149: model->kind = XSD_CONTENT_GROUP;
! 2150: model->u.group = (*tmp);
! 2151: } else {
! 2152: soap_error0(E_ERROR, "Parsing Schema: unresolved group 'ref' attribute");
! 2153: }
! 2154: break;
! 2155: }
! 2156: case XSD_CONTENT_CHOICE: {
! 2157: if (model->max_occurs != 1) {
! 2158: HashPosition pos;
! 2159: sdlContentModelPtr *tmp;
! 2160:
! 2161: zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
! 2162: while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
! 2163: (*tmp)->min_occurs = 0;
! 2164: (*tmp)->max_occurs = model->max_occurs;
! 2165: zend_hash_move_forward_ex(model->u.content, &pos);
! 2166: }
! 2167:
! 2168: model->kind = XSD_CONTENT_ALL;
! 2169: model->min_occurs = 1;
! 2170: model->max_occurs = 1;
! 2171: }
! 2172: }
! 2173: case XSD_CONTENT_SEQUENCE:
! 2174: case XSD_CONTENT_ALL: {
! 2175: sdlContentModelPtr *tmp;
! 2176:
! 2177: zend_hash_internal_pointer_reset(model->u.content);
! 2178: while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
! 2179: schema_content_model_fixup(ctx, *tmp);
! 2180: zend_hash_move_forward(model->u.content);
! 2181: }
! 2182: break;
! 2183: }
! 2184: default:
! 2185: break;
! 2186: }
! 2187: }
! 2188:
! 2189: static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
! 2190: {
! 2191: sdlTypePtr *tmp;
! 2192: sdlAttributePtr *attr;
! 2193:
! 2194: if (type->ref != NULL) {
! 2195: if (ctx->sdl->elements != NULL) {
! 2196: if (zend_hash_find(ctx->sdl->elements, type->ref, strlen(type->ref)+1, (void**)&tmp) == SUCCESS) {
! 2197: type->kind = (*tmp)->kind;
! 2198: type->encode = (*tmp)->encode;
! 2199: if ((*tmp)->nillable) {
! 2200: type->nillable = 1;
! 2201: }
! 2202: if ((*tmp)->fixed) {
! 2203: type->fixed = estrdup((*tmp)->fixed);
! 2204: }
! 2205: if ((*tmp)->def) {
! 2206: type->def = estrdup((*tmp)->def);
! 2207: }
! 2208: type->form = (*tmp)->form;
! 2209: } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
! 2210: type->encode = get_conversion(XSD_ANYXML);
! 2211: } else {
! 2212: soap_error0(E_ERROR, "Parsing Schema: unresolved element 'ref' attribute");
! 2213: }
! 2214: }
! 2215: efree(type->ref);
! 2216: type->ref = NULL;
! 2217: }
! 2218: if (type->elements) {
! 2219: zend_hash_internal_pointer_reset(type->elements);
! 2220: while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
! 2221: schema_type_fixup(ctx,*tmp);
! 2222: zend_hash_move_forward(type->elements);
! 2223: }
! 2224: }
! 2225: if (type->model) {
! 2226: schema_content_model_fixup(ctx, type->model);
! 2227: }
! 2228: if (type->attributes) {
! 2229: zend_hash_internal_pointer_reset(type->attributes);
! 2230: while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
! 2231: if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
! 2232: schema_attribute_fixup(ctx,*attr);
! 2233: zend_hash_move_forward(type->attributes);
! 2234: } else {
! 2235: ulong index;
! 2236:
! 2237: schema_attributegroup_fixup(ctx,*attr,type->attributes);
! 2238: zend_hash_get_current_key(type->attributes, NULL, &index, 0);
! 2239: zend_hash_index_del(type->attributes, index);
! 2240: }
! 2241: }
! 2242: }
! 2243: }
! 2244:
! 2245: void schema_pass2(sdlCtx *ctx)
! 2246: {
! 2247: sdlPtr sdl = ctx->sdl;
! 2248: sdlAttributePtr *attr;
! 2249: sdlTypePtr *type;
! 2250:
! 2251: if (ctx->attributes) {
! 2252: zend_hash_internal_pointer_reset(ctx->attributes);
! 2253: while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
! 2254: schema_attribute_fixup(ctx,*attr);
! 2255: zend_hash_move_forward(ctx->attributes);
! 2256: }
! 2257: }
! 2258: if (ctx->attributeGroups) {
! 2259: zend_hash_internal_pointer_reset(ctx->attributeGroups);
! 2260: while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
! 2261: schema_type_fixup(ctx,*type);
! 2262: zend_hash_move_forward(ctx->attributeGroups);
! 2263: }
! 2264: }
! 2265: if (sdl->elements) {
! 2266: zend_hash_internal_pointer_reset(sdl->elements);
! 2267: while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
! 2268: schema_type_fixup(ctx,*type);
! 2269: zend_hash_move_forward(sdl->elements);
! 2270: }
! 2271: }
! 2272: if (sdl->groups) {
! 2273: zend_hash_internal_pointer_reset(sdl->groups);
! 2274: while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
! 2275: schema_type_fixup(ctx,*type);
! 2276: zend_hash_move_forward(sdl->groups);
! 2277: }
! 2278: }
! 2279: if (sdl->types) {
! 2280: zend_hash_internal_pointer_reset(sdl->types);
! 2281: while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
! 2282: schema_type_fixup(ctx,*type);
! 2283: zend_hash_move_forward(sdl->types);
! 2284: }
! 2285: }
! 2286: if (ctx->attributes) {
! 2287: zend_hash_destroy(ctx->attributes);
! 2288: efree(ctx->attributes);
! 2289: }
! 2290: if (ctx->attributeGroups) {
! 2291: zend_hash_destroy(ctx->attributeGroups);
! 2292: efree(ctx->attributeGroups);
! 2293: }
! 2294: }
! 2295:
! 2296: void delete_model(void *handle)
! 2297: {
! 2298: sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
! 2299: switch (tmp->kind) {
! 2300: case XSD_CONTENT_ELEMENT:
! 2301: case XSD_CONTENT_GROUP:
! 2302: break;
! 2303: case XSD_CONTENT_SEQUENCE:
! 2304: case XSD_CONTENT_ALL:
! 2305: case XSD_CONTENT_CHOICE:
! 2306: zend_hash_destroy(tmp->u.content);
! 2307: efree(tmp->u.content);
! 2308: break;
! 2309: case XSD_CONTENT_GROUP_REF:
! 2310: efree(tmp->u.group_ref);
! 2311: break;
! 2312: default:
! 2313: break;
! 2314: }
! 2315: efree(tmp);
! 2316: }
! 2317:
! 2318: void delete_model_persistent(void *handle)
! 2319: {
! 2320: sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
! 2321: switch (tmp->kind) {
! 2322: case XSD_CONTENT_ELEMENT:
! 2323: case XSD_CONTENT_GROUP:
! 2324: break;
! 2325: case XSD_CONTENT_SEQUENCE:
! 2326: case XSD_CONTENT_ALL:
! 2327: case XSD_CONTENT_CHOICE:
! 2328: zend_hash_destroy(tmp->u.content);
! 2329: free(tmp->u.content);
! 2330: break;
! 2331: case XSD_CONTENT_GROUP_REF:
! 2332: free(tmp->u.group_ref);
! 2333: break;
! 2334: default:
! 2335: break;
! 2336: }
! 2337: free(tmp);
! 2338: }
! 2339:
! 2340: void delete_type(void *data)
! 2341: {
! 2342: sdlTypePtr type = *((sdlTypePtr*)data);
! 2343:
! 2344: if (type->name) {
! 2345: efree(type->name);
! 2346: }
! 2347: if (type->namens) {
! 2348: efree(type->namens);
! 2349: }
! 2350: if (type->def) {
! 2351: efree(type->def);
! 2352: }
! 2353: if (type->fixed) {
! 2354: efree(type->fixed);
! 2355: }
! 2356: if (type->elements) {
! 2357: zend_hash_destroy(type->elements);
! 2358: efree(type->elements);
! 2359: }
! 2360: if (type->attributes) {
! 2361: zend_hash_destroy(type->attributes);
! 2362: efree(type->attributes);
! 2363: }
! 2364: if (type->model) {
! 2365: delete_model((void**)&type->model);
! 2366: }
! 2367: if (type->restrictions) {
! 2368: delete_restriction_var_int(&type->restrictions->minExclusive);
! 2369: delete_restriction_var_int(&type->restrictions->minInclusive);
! 2370: delete_restriction_var_int(&type->restrictions->maxExclusive);
! 2371: delete_restriction_var_int(&type->restrictions->maxInclusive);
! 2372: delete_restriction_var_int(&type->restrictions->totalDigits);
! 2373: delete_restriction_var_int(&type->restrictions->fractionDigits);
! 2374: delete_restriction_var_int(&type->restrictions->length);
! 2375: delete_restriction_var_int(&type->restrictions->minLength);
! 2376: delete_restriction_var_int(&type->restrictions->maxLength);
! 2377: delete_restriction_var_char(&type->restrictions->whiteSpace);
! 2378: delete_restriction_var_char(&type->restrictions->pattern);
! 2379: if (type->restrictions->enumeration) {
! 2380: zend_hash_destroy(type->restrictions->enumeration);
! 2381: efree(type->restrictions->enumeration);
! 2382: }
! 2383: efree(type->restrictions);
! 2384: }
! 2385: efree(type);
! 2386: }
! 2387:
! 2388: void delete_type_persistent(void *data)
! 2389: {
! 2390: sdlTypePtr type = *((sdlTypePtr*)data);
! 2391: if (type->name) {
! 2392: free(type->name);
! 2393: }
! 2394: if (type->namens) {
! 2395: free(type->namens);
! 2396: }
! 2397: if (type->def) {
! 2398: free(type->def);
! 2399: }
! 2400: if (type->fixed) {
! 2401: free(type->fixed);
! 2402: }
! 2403: if (type->elements) {
! 2404: zend_hash_destroy(type->elements);
! 2405: free(type->elements);
! 2406: }
! 2407: if (type->attributes) {
! 2408: zend_hash_destroy(type->attributes);
! 2409: free(type->attributes);
! 2410: }
! 2411: if (type->model) {
! 2412: delete_model_persistent((void**)&type->model);
! 2413: }
! 2414: if (type->restrictions) {
! 2415: delete_restriction_var_int_persistent(&type->restrictions->minExclusive);
! 2416: delete_restriction_var_int_persistent(&type->restrictions->minInclusive);
! 2417: delete_restriction_var_int_persistent(&type->restrictions->maxExclusive);
! 2418: delete_restriction_var_int_persistent(&type->restrictions->maxInclusive);
! 2419: delete_restriction_var_int_persistent(&type->restrictions->totalDigits);
! 2420: delete_restriction_var_int_persistent(&type->restrictions->fractionDigits);
! 2421: delete_restriction_var_int_persistent(&type->restrictions->length);
! 2422: delete_restriction_var_int_persistent(&type->restrictions->minLength);
! 2423: delete_restriction_var_int_persistent(&type->restrictions->maxLength);
! 2424: delete_restriction_var_char_persistent(&type->restrictions->whiteSpace);
! 2425: delete_restriction_var_char_persistent(&type->restrictions->pattern);
! 2426: if (type->restrictions->enumeration) {
! 2427: zend_hash_destroy(type->restrictions->enumeration);
! 2428: free(type->restrictions->enumeration);
! 2429: }
! 2430: free(type->restrictions);
! 2431: }
! 2432: free(type);
! 2433: }
! 2434:
! 2435: void delete_extra_attribute(void *attribute)
! 2436: {
! 2437: sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
! 2438:
! 2439: if (attr->ns) {
! 2440: efree(attr->ns);
! 2441: }
! 2442: if (attr->val) {
! 2443: efree(attr->val);
! 2444: }
! 2445: efree(attr);
! 2446: }
! 2447:
! 2448: void delete_extra_attribute_persistent(void *attribute)
! 2449: {
! 2450: sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
! 2451:
! 2452: if (attr->ns) {
! 2453: free(attr->ns);
! 2454: }
! 2455: if (attr->val) {
! 2456: free(attr->val);
! 2457: }
! 2458: free(attr);
! 2459: }
! 2460:
! 2461: void delete_attribute(void *attribute)
! 2462: {
! 2463: sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
! 2464:
! 2465: if (attr->def) {
! 2466: efree(attr->def);
! 2467: }
! 2468: if (attr->fixed) {
! 2469: efree(attr->fixed);
! 2470: }
! 2471: if (attr->name) {
! 2472: efree(attr->name);
! 2473: }
! 2474: if (attr->namens) {
! 2475: efree(attr->namens);
! 2476: }
! 2477: if (attr->ref) {
! 2478: efree(attr->ref);
! 2479: }
! 2480: if (attr->extraAttributes) {
! 2481: zend_hash_destroy(attr->extraAttributes);
! 2482: efree(attr->extraAttributes);
! 2483: }
! 2484: efree(attr);
! 2485: }
! 2486:
! 2487: void delete_attribute_persistent(void *attribute)
! 2488: {
! 2489: sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
! 2490:
! 2491: if (attr->def) {
! 2492: free(attr->def);
! 2493: }
! 2494: if (attr->fixed) {
! 2495: free(attr->fixed);
! 2496: }
! 2497: if (attr->name) {
! 2498: free(attr->name);
! 2499: }
! 2500: if (attr->namens) {
! 2501: free(attr->namens);
! 2502: }
! 2503: if (attr->ref) {
! 2504: free(attr->ref);
! 2505: }
! 2506: if (attr->extraAttributes) {
! 2507: zend_hash_destroy(attr->extraAttributes);
! 2508: free(attr->extraAttributes);
! 2509: }
! 2510: free(attr);
! 2511: }
! 2512:
! 2513: void delete_restriction_var_int(void *rvi)
! 2514: {
! 2515: sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
! 2516: if (ptr) {
! 2517: efree(ptr);
! 2518: }
! 2519: }
! 2520:
! 2521: void delete_restriction_var_int_persistent(void *rvi)
! 2522: {
! 2523: sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
! 2524: if (ptr) {
! 2525: free(ptr);
! 2526: }
! 2527: }
! 2528:
! 2529: void delete_restriction_var_char(void *srvc)
! 2530: {
! 2531: sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
! 2532: if (ptr) {
! 2533: if (ptr->value) {
! 2534: efree(ptr->value);
! 2535: }
! 2536: efree(ptr);
! 2537: }
! 2538: }
! 2539:
! 2540: void delete_restriction_var_char_persistent(void *srvc)
! 2541: {
! 2542: sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
! 2543: if (ptr) {
! 2544: if (ptr->value) {
! 2545: free(ptr->value);
! 2546: }
! 2547: free(ptr);
! 2548: }
! 2549: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>