Annotation of embedaddon/php/ext/soap/php_schema.c, revision 1.1.1.5
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.5 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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: */
1.1.1.2 misho 20: /* $Id$ */
1.1 misho 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);
1.1.1.4 misho 1084: } else {
1085: xmlAttrPtr ns = get_attribute(groupType->properties, "targetNamespace");
1086: if (ns == NULL) {
1087: ns = tns;
1088: }
1089: if (ns) {
1090: smart_str_appends(&key, (char*)ns->children->content);
1091: }
1.1 misho 1092: }
1093: smart_str_appendc(&key, ':');
1094: smart_str_appends(&key, type);
1095: smart_str_0(&key);
1096:
1097: newModel = emalloc(sizeof(sdlContentModel));
1098: newModel->kind = XSD_CONTENT_GROUP_REF;
1099: newModel->u.group_ref = estrdup(key.c);
1100:
1101: if (type) {efree(type);}
1102: if (ns) {efree(ns);}
1103: } else {
1104: newModel = emalloc(sizeof(sdlContentModel));
1105: newModel->kind = XSD_CONTENT_SEQUENCE; /* will be redefined */
1106: newModel->u.content = emalloc(sizeof(HashTable));
1107: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1108:
1109: smart_str_appends(&key, (char*)ns->children->content);
1110: smart_str_appendc(&key, ':');
1111: smart_str_appends(&key, (char*)name->children->content);
1112: smart_str_0(&key);
1113: }
1114:
1115: if (cur_type == NULL) {
1116: sdlTypePtr newType;
1117:
1118: newType = emalloc(sizeof(sdlType));
1119: memset(newType, 0, sizeof(sdlType));
1120:
1121: if (sdl->groups == NULL) {
1122: sdl->groups = emalloc(sizeof(HashTable));
1123: zend_hash_init(sdl->groups, 0, NULL, delete_type, 0);
1124: }
1125: if (zend_hash_add(sdl->groups, key.c, key.len+1, (void**)&newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
1126: soap_error1(E_ERROR, "Parsing Schema: group '%s' already defined", key.c);
1127: }
1128:
1129: cur_type = newType;
1130: }
1131: smart_str_free(&key);
1132:
1133: if (model == NULL) {
1134: cur_type->model = newModel;
1135: } else {
1136: zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
1137: }
1138: } else {
1139: soap_error0(E_ERROR, "Parsing Schema: group has no 'name' nor 'ref' attributes");
1140: }
1141:
1142: schema_min_max(groupType, newModel);
1143:
1144: trav = groupType->children;
1145: if (trav != NULL && node_is_equal(trav,"annotation")) {
1146: /* TODO: <annotation> support */
1147: trav = trav->next;
1148: }
1149: if (trav != NULL) {
1150: if (node_is_equal(trav,"choice")) {
1151: if (ref != NULL) {
1152: soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
1153: }
1154: newModel->kind = XSD_CONTENT_CHOICE;
1155: schema_choice(sdl, tns, trav, cur_type, newModel);
1156: trav = trav->next;
1157: } else if (node_is_equal(trav,"sequence")) {
1158: if (ref != NULL) {
1159: soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
1160: }
1161: newModel->kind = XSD_CONTENT_SEQUENCE;
1162: schema_sequence(sdl, tns, trav, cur_type, newModel);
1163: trav = trav->next;
1164: } else if (node_is_equal(trav,"all")) {
1165: if (ref != NULL) {
1166: soap_error0(E_ERROR, "Parsing Schema: group has both 'ref' attribute and subcontent");
1167: }
1168: newModel->kind = XSD_CONTENT_ALL;
1169: schema_all(sdl, tns, trav, cur_type, newModel);
1170: trav = trav->next;
1171: } else {
1172: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
1173: }
1174: }
1175: if (trav != NULL) {
1176: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in group", trav->name);
1177: }
1178: return TRUE;
1179: }
1180: /*
1181: <choice
1182: id = ID
1183: maxOccurs = (nonNegativeInteger | unbounded) : 1
1184: minOccurs = nonNegativeInteger : 1
1185: {any attributes with non-schema namespace . . .}>
1186: Content: (annotation?, (element | group | choice | sequence | any)*)
1187: </choice>
1188: */
1189: static int schema_choice(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr choiceType, sdlTypePtr cur_type, sdlContentModelPtr model)
1190: {
1191: xmlNodePtr trav;
1192: sdlContentModelPtr newModel;
1193:
1194: newModel = emalloc(sizeof(sdlContentModel));
1195: newModel->kind = XSD_CONTENT_CHOICE;
1196: newModel->u.content = emalloc(sizeof(HashTable));
1197: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1198: if (model == NULL) {
1199: cur_type->model = newModel;
1200: } else {
1201: zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
1202: }
1203:
1204: schema_min_max(choiceType, newModel);
1205:
1206: trav = choiceType->children;
1207: if (trav != NULL && node_is_equal(trav,"annotation")) {
1208: /* TODO: <annotation> support */
1209: trav = trav->next;
1210: }
1211: while (trav != NULL) {
1212: if (node_is_equal(trav,"element")) {
1213: schema_element(sdl, tns, trav, cur_type, newModel);
1214: } else if (node_is_equal(trav,"group")) {
1215: schema_group(sdl, tns, trav, cur_type, newModel);
1216: } else if (node_is_equal(trav,"choice")) {
1217: schema_choice(sdl, tns, trav, cur_type, newModel);
1218: } else if (node_is_equal(trav,"sequence")) {
1219: schema_sequence(sdl, tns, trav, cur_type, newModel);
1220: } else if (node_is_equal(trav,"any")) {
1221: schema_any(sdl, tns, trav, cur_type, newModel);
1222: } else {
1223: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in choice", trav->name);
1224: }
1225: trav = trav->next;
1226: }
1227: return TRUE;
1228: }
1229:
1230: /*
1231: <sequence
1232: id = ID
1233: maxOccurs = (nonNegativeInteger | unbounded) : 1
1234: minOccurs = nonNegativeInteger : 1
1235: {any attributes with non-schema namespace . . .}>
1236: Content: (annotation?, (element | group | choice | sequence | any)*)
1237: </sequence>
1238: */
1239: static int schema_sequence(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr seqType, sdlTypePtr cur_type, sdlContentModelPtr model)
1240: {
1241: xmlNodePtr trav;
1242: sdlContentModelPtr newModel;
1243:
1244: newModel = emalloc(sizeof(sdlContentModel));
1245: newModel->kind = XSD_CONTENT_SEQUENCE;
1246: newModel->u.content = emalloc(sizeof(HashTable));
1247: zend_hash_init(newModel->u.content, 0, NULL, delete_model, 0);
1248: if (model == NULL) {
1249: cur_type->model = newModel;
1250: } else {
1251: zend_hash_next_index_insert(model->u.content,&newModel,sizeof(sdlContentModelPtr), NULL);
1252: }
1253:
1254: schema_min_max(seqType, newModel);
1255:
1256: trav = seqType->children;
1257: if (trav != NULL && node_is_equal(trav,"annotation")) {
1258: /* TODO: <annotation> support */
1259: trav = trav->next;
1260: }
1261: while (trav != NULL) {
1262: if (node_is_equal(trav,"element")) {
1263: schema_element(sdl, tns, trav, cur_type, newModel);
1264: } else if (node_is_equal(trav,"group")) {
1265: schema_group(sdl, tns, trav, cur_type, newModel);
1266: } else if (node_is_equal(trav,"choice")) {
1267: schema_choice(sdl, tns, trav, cur_type, newModel);
1268: } else if (node_is_equal(trav,"sequence")) {
1269: schema_sequence(sdl, tns, trav, cur_type, newModel);
1270: } else if (node_is_equal(trav,"any")) {
1271: schema_any(sdl, tns, trav, cur_type, newModel);
1272: } else {
1273: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in sequence", trav->name);
1274: }
1275: trav = trav->next;
1276: }
1277: return TRUE;
1278: }
1279:
1280: /*
1281: <any
1282: id = ID
1283: maxOccurs = (nonNegativeInteger | unbounded) : 1
1284: minOccurs = nonNegativeInteger : 1
1285: namespace = ((##any | ##other) | List of (anyURI | (##targetNamespace | ##local)) ) : ##any
1286: processContents = (lax | skip | strict) : strict
1287: {any attributes with non-schema namespace . . .}>
1288: Content: (annotation?)
1289: </any>
1290: */
1291: static int schema_any(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr anyType, sdlTypePtr cur_type, sdlContentModelPtr model)
1292: {
1293: if (model != NULL) {
1294: sdlContentModelPtr newModel;
1295:
1296: newModel = emalloc(sizeof(sdlContentModel));
1297: newModel->kind = XSD_CONTENT_ANY;
1298:
1299: schema_min_max(anyType, newModel);
1300:
1301: zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
1302: }
1303: return TRUE;
1304: }
1305:
1306: /*
1307: <complexContent
1308: id = ID
1309: mixed = boolean
1310: {any attributes with non-schema namespace . . .}>
1311: Content: (annotation?, (restriction | extension))
1312: </complexContent>
1313: */
1314: static int schema_complexContent(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compCont, sdlTypePtr cur_type)
1315: {
1316: xmlNodePtr trav;
1317:
1318: trav = compCont->children;
1319: if (trav != NULL && node_is_equal(trav,"annotation")) {
1320: /* TODO: <annotation> support */
1321: trav = trav->next;
1322: }
1323: if (trav != NULL) {
1324: if (node_is_equal(trav, "restriction")) {
1325: cur_type->kind = XSD_TYPEKIND_RESTRICTION;
1326: schema_restriction_complexContent(sdl, tns, trav, cur_type);
1327: trav = trav->next;
1328: } else if (node_is_equal(trav, "extension")) {
1329: cur_type->kind = XSD_TYPEKIND_EXTENSION;
1330: schema_extension_complexContent(sdl, tns, trav, cur_type);
1331: trav = trav->next;
1332: } else {
1333: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
1334: }
1335: } else {
1336: soap_error0(E_ERROR, "Parsing Schema: <restriction> or <extension> expected in complexContent");
1337: }
1338: if (trav != NULL) {
1339: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexContent", trav->name);
1340: }
1341:
1342: return TRUE;
1343: }
1344:
1345: /*
1346: <complexType
1347: abstract = boolean : false
1348: block = (#all | List of (extension | restriction))
1349: final = (#all | List of (extension | restriction))
1350: id = ID
1351: mixed = boolean : false
1352: name = NCName
1353: {any attributes with non-schema namespace . . .}>
1354: Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
1355: </complexType>
1356: */
1357: static int schema_complexType(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr compType, sdlTypePtr cur_type)
1358: {
1359: xmlNodePtr trav;
1360: xmlAttrPtr attrs, name, ns;
1361:
1362: attrs = compType->properties;
1363: ns = get_attribute(attrs, "targetNamespace");
1364: if (ns == NULL) {
1365: ns = tns;
1366: }
1367:
1368: name = get_attribute(attrs, "name");
1369: if (cur_type != NULL) {
1370: /* Anonymous type inside <element> */
1371: sdlTypePtr newType, *ptr;
1372:
1373: newType = emalloc(sizeof(sdlType));
1374: memset(newType, 0, sizeof(sdlType));
1375: newType->kind = XSD_TYPEKIND_COMPLEX;
1376: if (name != NULL) {
1377: newType->name = estrdup((char*)name->children->content);
1378: newType->namens = estrdup((char*)ns->children->content);
1379: } else {
1380: newType->name = estrdup(cur_type->name);
1381: newType->namens = estrdup(cur_type->namens);
1382: }
1383:
1384: zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
1385:
1386: if (sdl->encoders == NULL) {
1387: sdl->encoders = emalloc(sizeof(HashTable));
1388: zend_hash_init(sdl->encoders, 0, NULL, delete_encoder, 0);
1389: }
1390: cur_type->encode = emalloc(sizeof(encode));
1391: memset(cur_type->encode, 0, sizeof(encode));
1392: cur_type->encode->details.ns = estrdup(newType->namens);
1393: cur_type->encode->details.type_str = estrdup(newType->name);
1394: cur_type->encode->details.sdl_type = *ptr;
1395: cur_type->encode->to_xml = sdl_guess_convert_xml;
1396: cur_type->encode->to_zval = sdl_guess_convert_zval;
1397: zend_hash_next_index_insert(sdl->encoders, &cur_type->encode, sizeof(encodePtr), NULL);
1398:
1399: cur_type =*ptr;
1400:
1401: } else if (name) {
1402: sdlTypePtr newType, *ptr;
1403:
1404: newType = emalloc(sizeof(sdlType));
1405: memset(newType, 0, sizeof(sdlType));
1406: newType->kind = XSD_TYPEKIND_COMPLEX;
1407: newType->name = estrdup((char*)name->children->content);
1408: newType->namens = estrdup((char*)ns->children->content);
1409:
1410: zend_hash_next_index_insert(sdl->types, &newType, sizeof(sdlTypePtr), (void **)&ptr);
1411:
1412: cur_type = (*ptr);
1413: create_encoder(sdl, cur_type, ns->children->content, name->children->content);
1414: } else {
1415: soap_error0(E_ERROR, "Parsing Schema: complexType has no 'name' attribute");
1416: return FALSE;
1417: }
1418:
1419: trav = compType->children;
1420: if (trav != NULL && node_is_equal(trav, "annotation")) {
1421: /* TODO: <annotation> support */
1422: trav = trav->next;
1423: }
1424: if (trav != NULL) {
1425: if (node_is_equal(trav,"simpleContent")) {
1426: schema_simpleContent(sdl, tns, trav, cur_type);
1427: trav = trav->next;
1428: } else if (node_is_equal(trav,"complexContent")) {
1429: schema_complexContent(sdl, tns, trav, cur_type);
1430: trav = trav->next;
1431: } else {
1432: if (node_is_equal(trav,"group")) {
1433: schema_group(sdl, tns, trav, cur_type, NULL);
1434: trav = trav->next;
1435: } else if (node_is_equal(trav,"all")) {
1436: schema_all(sdl, tns, trav, cur_type, NULL);
1437: trav = trav->next;
1438: } else if (node_is_equal(trav,"choice")) {
1439: schema_choice(sdl, tns, trav, cur_type, NULL);
1440: trav = trav->next;
1441: } else if (node_is_equal(trav,"sequence")) {
1442: schema_sequence(sdl, tns, trav, cur_type, NULL);
1443: trav = trav->next;
1444: }
1445: while (trav != NULL) {
1446: if (node_is_equal(trav,"attribute")) {
1447: schema_attribute(sdl, tns, trav, cur_type, NULL);
1448: } else if (node_is_equal(trav,"attributeGroup")) {
1449: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
1450: } else if (node_is_equal(trav,"anyAttribute")) {
1451: /* TODO: <anyAttribute> support */
1452: trav = trav->next;
1453: break;
1454: } else {
1455: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
1456: }
1457: trav = trav->next;
1458: }
1459: }
1460: }
1461: if (trav != NULL) {
1462: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in complexType", trav->name);
1463: }
1464: return TRUE;
1465: }
1466: /*
1467: <element
1468: abstract = boolean : false
1469: block = (#all | List of (extension | restriction | substitution))
1470: default = string
1471: final = (#all | List of (extension | restriction))
1472: fixed = string
1473: form = (qualified | unqualified)
1474: id = ID
1475: maxOccurs = (nonNegativeInteger | unbounded) : 1
1476: minOccurs = nonNegativeInteger : 1
1477: name = NCName
1478: nillable = boolean : false
1479: ref = QName
1480: substitutionGroup = QName
1481: type = QName
1482: {any attributes with non-schema namespace . . .}>
1483: Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
1484: </element>
1485: */
1486: static int schema_element(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr element, sdlTypePtr cur_type, sdlContentModelPtr model)
1487: {
1488: xmlNodePtr trav;
1489: xmlAttrPtr attrs, attr, ns, name, type, ref = NULL;
1490:
1491: attrs = element->properties;
1492: ns = get_attribute(attrs, "targetNamespace");
1493: if (ns == NULL) {
1494: ns = tns;
1495: }
1496:
1497: name = get_attribute(attrs, "name");
1498: if (name == NULL) {
1499: name = ref = get_attribute(attrs, "ref");
1500: }
1501:
1502: if (name) {
1503: HashTable *addHash;
1504: sdlTypePtr newType;
1505: smart_str key = {0};
1506:
1507: newType = emalloc(sizeof(sdlType));
1508: memset(newType, 0, sizeof(sdlType));
1509:
1510: if (ref) {
1511: smart_str nscat = {0};
1512: char *type, *ns;
1513: xmlNsPtr nsptr;
1514:
1515: parse_namespace(ref->children->content, &type, &ns);
1516: nsptr = xmlSearchNs(element->doc, element, BAD_CAST(ns));
1517: if (nsptr != NULL) {
1518: smart_str_appends(&nscat, (char*)nsptr->href);
1519: newType->namens = estrdup((char*)nsptr->href);
1.1.1.4 misho 1520: } else {
1521: xmlAttrPtr ns = get_attribute(attrs, "targetNamespace");
1522: if (ns == NULL) {
1523: ns = tns;
1524: }
1525: if (ns) {
1526: smart_str_appends(&nscat, (char*)ns->children->content);
1527: }
1.1 misho 1528: }
1529: smart_str_appendc(&nscat, ':');
1530: smart_str_appends(&nscat, type);
1531: newType->name = estrdup(type);
1532: smart_str_0(&nscat);
1533: if (type) {efree(type);}
1534: if (ns) {efree(ns);}
1535: newType->ref = estrdup(nscat.c);
1536: smart_str_free(&nscat);
1537: } else {
1538: newType->name = estrdup((char*)name->children->content);
1539: newType->namens = estrdup((char*)ns->children->content);
1540: }
1541:
1542: newType->nillable = FALSE;
1543:
1544: if (cur_type == NULL) {
1545: if (sdl->elements == NULL) {
1546: sdl->elements = emalloc(sizeof(HashTable));
1547: zend_hash_init(sdl->elements, 0, NULL, delete_type, 0);
1548: }
1549: addHash = sdl->elements;
1550: smart_str_appends(&key, newType->namens);
1551: smart_str_appendc(&key, ':');
1552: smart_str_appends(&key, newType->name);
1553: } else {
1554: if (cur_type->elements == NULL) {
1555: cur_type->elements = emalloc(sizeof(HashTable));
1556: zend_hash_init(cur_type->elements, 0, NULL, delete_type, 0);
1557: }
1558: addHash = cur_type->elements;
1559: smart_str_appends(&key, newType->name);
1560: }
1561:
1562: smart_str_0(&key);
1563: if (zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
1564: if (cur_type == NULL) {
1565: soap_error1(E_ERROR, "Parsing Schema: element '%s' already defined", key.c);
1566: } else {
1567: zend_hash_next_index_insert(addHash, &newType, sizeof(sdlTypePtr), NULL);
1568: }
1569: }
1570: smart_str_free(&key);
1571:
1572: if (model != NULL) {
1573: sdlContentModelPtr newModel = emalloc(sizeof(sdlContentModel));
1574:
1575: newModel->kind = XSD_CONTENT_ELEMENT;
1576: newModel->u.element = newType;
1577:
1578: schema_min_max(element, newModel);
1579:
1580:
1581: zend_hash_next_index_insert(model->u.content, &newModel, sizeof(sdlContentModelPtr), NULL);
1582: }
1583: cur_type = newType;
1584: } else {
1585: soap_error0(E_ERROR, "Parsing Schema: element has no 'name' nor 'ref' attributes");
1586: }
1587:
1588: /* nillable = boolean : false */
1589: attrs = element->properties;
1590: attr = get_attribute(attrs, "nillable");
1591: if (attr) {
1592: if (ref != NULL) {
1593: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'nillable' attributes");
1594: }
1595: if (!stricmp((char*)attr->children->content, "true") ||
1596: !stricmp((char*)attr->children->content, "1")) {
1597: cur_type->nillable = TRUE;
1598: } else {
1599: cur_type->nillable = FALSE;
1600: }
1601: } else {
1602: cur_type->nillable = FALSE;
1603: }
1604:
1605: attr = get_attribute(attrs, "fixed");
1606: if (attr) {
1607: if (ref != NULL) {
1608: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
1609: }
1610: cur_type->fixed = estrdup((char*)attr->children->content);
1611: }
1612:
1613: attr = get_attribute(attrs, "default");
1614: if (attr) {
1615: if (ref != NULL) {
1616: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'fixed' attributes");
1617: } else if (ref != NULL) {
1618: soap_error0(E_ERROR, "Parsing Schema: element has both 'default' and 'fixed' attributes");
1619: }
1620: cur_type->def = estrdup((char*)attr->children->content);
1621: }
1622:
1623: /* form */
1624: attr = get_attribute(attrs, "form");
1625: if (attr) {
1626: if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
1627: cur_type->form = XSD_FORM_QUALIFIED;
1628: } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
1629: cur_type->form = XSD_FORM_UNQUALIFIED;
1630: } else {
1631: cur_type->form = XSD_FORM_DEFAULT;
1632: }
1633: } else {
1634: cur_type->form = XSD_FORM_DEFAULT;
1635: }
1636: if (cur_type->form == XSD_FORM_DEFAULT) {
1637: xmlNodePtr parent = element->parent;
1638: while (parent) {
1639: if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
1640: xmlAttrPtr def;
1641: def = get_attribute(parent->properties, "elementFormDefault");
1642: if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
1643: cur_type->form = XSD_FORM_UNQUALIFIED;
1644: } else {
1645: cur_type->form = XSD_FORM_QUALIFIED;
1646: }
1647: break;
1648: }
1649: parent = parent->parent;
1650: }
1651: if (parent == NULL) {
1652: cur_type->form = XSD_FORM_UNQUALIFIED;
1653: }
1654: }
1655:
1656: /* type = QName */
1657: type = get_attribute(attrs, "type");
1658: if (type) {
1659: char *cptype, *str_ns;
1660: xmlNsPtr nsptr;
1661:
1662: if (ref != NULL) {
1663: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' and 'type' attributes");
1664: }
1665: parse_namespace(type->children->content, &cptype, &str_ns);
1666: nsptr = xmlSearchNs(element->doc, element, BAD_CAST(str_ns));
1667: if (nsptr != NULL) {
1668: cur_type->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
1669: }
1670: if (str_ns) {efree(str_ns);}
1671: if (cptype) {efree(cptype);}
1672: }
1673:
1674: trav = element->children;
1675: if (trav != NULL && node_is_equal(trav, "annotation")) {
1676: /* TODO: <annotation> support */
1677: trav = trav->next;
1678: }
1679: if (trav != NULL) {
1680: if (node_is_equal(trav,"simpleType")) {
1681: if (ref != NULL) {
1682: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
1683: } else if (type != NULL) {
1684: soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
1685: }
1686: schema_simpleType(sdl, tns, trav, cur_type);
1687: trav = trav->next;
1688: } else if (node_is_equal(trav,"complexType")) {
1689: if (ref != NULL) {
1690: soap_error0(E_ERROR, "Parsing Schema: element has both 'ref' attribute and subtype");
1691: } else if (type != NULL) {
1692: soap_error0(E_ERROR, "Parsing Schema: element has both 'type' attribute and subtype");
1693: }
1694: schema_complexType(sdl, tns, trav, cur_type);
1695: trav = trav->next;
1696: }
1697: }
1698: while (trav != NULL) {
1699: if (node_is_equal(trav,"unique")) {
1700: /* TODO: <unique> support */
1701: } else if (node_is_equal(trav,"key")) {
1702: /* TODO: <key> support */
1703: } else if (node_is_equal(trav,"keyref")) {
1704: /* TODO: <keyref> support */
1705: } else {
1706: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in element", trav->name);
1707: }
1708: trav = trav->next;
1709: }
1710:
1711: return TRUE;
1712: }
1713:
1714: /*
1715: <attribute
1716: default = string
1717: fixed = string
1718: form = (qualified | unqualified)
1719: id = ID
1720: name = NCName
1721: ref = QName
1722: type = QName
1723: use = (optional | prohibited | required) : optional
1724: {any attributes with non-schema namespace . . .}>
1725: Content: (annotation?, (simpleType?))
1726: </attribute>
1727: */
1728: static int schema_attribute(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrType, sdlTypePtr cur_type, sdlCtx *ctx)
1729: {
1730: sdlAttributePtr newAttr;
1731: xmlAttrPtr attr, name, ref = NULL, type = NULL;
1732: xmlNodePtr trav;
1733:
1734: name = get_attribute(attrType->properties, "name");
1735: if (name == NULL) {
1736: name = ref = get_attribute(attrType->properties, "ref");
1737: }
1738: if (name) {
1739: HashTable *addHash;
1740: smart_str key = {0};
1741:
1742: newAttr = emalloc(sizeof(sdlAttribute));
1743: memset(newAttr, 0, sizeof(sdlAttribute));
1744:
1745: if (ref) {
1746: char *attr_name, *ns;
1747: xmlNsPtr nsptr;
1748:
1749: parse_namespace(ref->children->content, &attr_name, &ns);
1750: nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(ns));
1751: if (nsptr != NULL) {
1752: smart_str_appends(&key, (char*)nsptr->href);
1753: newAttr->namens = estrdup((char*)nsptr->href);
1.1.1.4 misho 1754: } else {
1755: xmlAttrPtr ns = get_attribute(attrType->properties, "targetNamespace");
1756: if (ns == NULL) {
1757: ns = tns;
1758: }
1759: if (ns) {
1760: smart_str_appends(&key, (char*)ns->children->content);
1761: }
1.1 misho 1762: }
1763: smart_str_appendc(&key, ':');
1764: smart_str_appends(&key, attr_name);
1765: smart_str_0(&key);
1766: newAttr->ref = estrdup(key.c);
1767: if (attr_name) {efree(attr_name);}
1768: if (ns) {efree(ns);}
1769: } else {
1770: xmlAttrPtr ns;
1771:
1772: ns = get_attribute(attrType->properties, "targetNamespace");
1773: if (ns == NULL) {
1774: ns = tns;
1775: }
1776: if (ns != NULL) {
1777: smart_str_appends(&key, (char*)ns->children->content);
1778: smart_str_appendc(&key, ':');
1779: newAttr->namens = estrdup((char*)ns->children->content);
1780: }
1781: smart_str_appends(&key, (char*)name->children->content);
1782: smart_str_0(&key);
1783: }
1784:
1785: if (cur_type == NULL) {
1786: addHash = ctx->attributes;
1787: } else {
1788: if (cur_type->attributes == NULL) {
1789: cur_type->attributes = emalloc(sizeof(HashTable));
1790: zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
1791: }
1792: addHash = cur_type->attributes;
1793: }
1794:
1795: if (zend_hash_add(addHash, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL) != SUCCESS) {
1796: soap_error1(E_ERROR, "Parsing Schema: attribute '%s' already defined", key.c);
1797: }
1798: smart_str_free(&key);
1799: } else{
1800: soap_error0(E_ERROR, "Parsing Schema: attribute has no 'name' nor 'ref' attributes");
1801: }
1802:
1803: /* type = QName */
1804: type = get_attribute(attrType->properties, "type");
1805: if (type) {
1806: char *cptype, *str_ns;
1807: xmlNsPtr nsptr;
1808:
1809: if (ref != NULL) {
1810: soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' and 'type' attributes");
1811: }
1812: parse_namespace(type->children->content, &cptype, &str_ns);
1813: nsptr = xmlSearchNs(attrType->doc, attrType, BAD_CAST(str_ns));
1814: if (nsptr != NULL) {
1815: newAttr->encode = get_create_encoder(sdl, cur_type, nsptr->href, BAD_CAST(cptype));
1816: }
1817: if (str_ns) {efree(str_ns);}
1818: if (cptype) {efree(cptype);}
1819: }
1820:
1821: attr = attrType->properties;
1822: while (attr != NULL) {
1823: if (attr_is_equal_ex(attr, "default", SCHEMA_NAMESPACE)) {
1824: newAttr->def = estrdup((char*)attr->children->content);
1825: } else if (attr_is_equal_ex(attr, "fixed", SCHEMA_NAMESPACE)) {
1826: newAttr->fixed = estrdup((char*)attr->children->content);
1827: } else if (attr_is_equal_ex(attr, "form", SCHEMA_NAMESPACE)) {
1828: if (strncmp((char*)attr->children->content, "qualified", sizeof("qualified")) == 0) {
1829: newAttr->form = XSD_FORM_QUALIFIED;
1830: } else if (strncmp((char*)attr->children->content, "unqualified", sizeof("unqualified")) == 0) {
1831: newAttr->form = XSD_FORM_UNQUALIFIED;
1832: } else {
1833: newAttr->form = XSD_FORM_DEFAULT;
1834: }
1835: } else if (attr_is_equal_ex(attr, "id", SCHEMA_NAMESPACE)) {
1836: /* skip */
1837: } else if (attr_is_equal_ex(attr, "name", SCHEMA_NAMESPACE)) {
1838: newAttr->name = estrdup((char*)attr->children->content);
1839: } else if (attr_is_equal_ex(attr, "ref", SCHEMA_NAMESPACE)) {
1840: /* already processed */
1841: } else if (attr_is_equal_ex(attr, "type", SCHEMA_NAMESPACE)) {
1842: /* already processed */
1843: } else if (attr_is_equal_ex(attr, "use", SCHEMA_NAMESPACE)) {
1844: if (strncmp((char*)attr->children->content, "prohibited", sizeof("prohibited")) == 0) {
1845: newAttr->use = XSD_USE_PROHIBITED;
1846: } else if (strncmp((char*)attr->children->content, "required", sizeof("required")) == 0) {
1847: newAttr->use = XSD_USE_REQUIRED;
1848: } else if (strncmp((char*)attr->children->content, "optional", sizeof("optional")) == 0) {
1849: newAttr->use = XSD_USE_OPTIONAL;
1850: } else {
1851: newAttr->use = XSD_USE_DEFAULT;
1852: }
1853: } else {
1854: xmlNsPtr nsPtr = attr_find_ns(attr);
1855:
1856: if (strncmp((char*)nsPtr->href, SCHEMA_NAMESPACE, sizeof(SCHEMA_NAMESPACE))) {
1857: smart_str key2 = {0};
1858: sdlExtraAttributePtr ext;
1859: xmlNsPtr nsptr;
1860: char *value, *ns;
1861:
1862: ext = emalloc(sizeof(sdlExtraAttribute));
1863: memset(ext, 0, sizeof(sdlExtraAttribute));
1864: parse_namespace(attr->children->content, &value, &ns);
1865: nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns));
1866: if (nsptr) {
1867: ext->ns = estrdup((char*)nsptr->href);
1868: ext->val = estrdup(value);
1869: } else {
1870: ext->val = estrdup((char*)attr->children->content);
1871: }
1872: if (ns) {efree(ns);}
1873: efree(value);
1874:
1875: if (!newAttr->extraAttributes) {
1876: newAttr->extraAttributes = emalloc(sizeof(HashTable));
1877: zend_hash_init(newAttr->extraAttributes, 0, NULL, delete_extra_attribute, 0);
1878: }
1879:
1880: smart_str_appends(&key2, (char*)nsPtr->href);
1881: smart_str_appendc(&key2, ':');
1882: smart_str_appends(&key2, (char*)attr->name);
1883: smart_str_0(&key2);
1884: zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &ext, sizeof(sdlExtraAttributePtr), NULL);
1885: smart_str_free(&key2);
1886: }
1887: }
1888: attr = attr->next;
1889: }
1890: if (newAttr->form == XSD_FORM_DEFAULT) {
1891: xmlNodePtr parent = attrType->parent;
1892: while (parent) {
1893: if (node_is_equal_ex(parent, "schema", SCHEMA_NAMESPACE)) {
1894: xmlAttrPtr def;
1895: def = get_attribute(parent->properties, "attributeFormDefault");
1896: if(def == NULL || strncmp((char*)def->children->content, "qualified", sizeof("qualified"))) {
1897: newAttr->form = XSD_FORM_UNQUALIFIED;
1898: } else {
1899: newAttr->form = XSD_FORM_QUALIFIED;
1900: }
1901: break;
1902: }
1903: parent = parent->parent;
1904: }
1905: if (parent == NULL) {
1906: newAttr->form = XSD_FORM_UNQUALIFIED;
1907: }
1908: }
1909: trav = attrType->children;
1910: if (trav != NULL && node_is_equal(trav, "annotation")) {
1911: /* TODO: <annotation> support */
1912: trav = trav->next;
1913: }
1914: if (trav != NULL) {
1915: if (node_is_equal(trav,"simpleType")) {
1916: sdlTypePtr dummy_type;
1917: if (ref != NULL) {
1918: soap_error0(E_ERROR, "Parsing Schema: attribute has both 'ref' attribute and subtype");
1919: } else if (type != NULL) {
1920: soap_error0(E_ERROR, "Parsing Schema: attribute has both 'type' attribute and subtype");
1921: }
1922: dummy_type = emalloc(sizeof(sdlType));
1923: memset(dummy_type, 0, sizeof(sdlType));
1924: {
1925: smart_str anonymous = {0};
1926:
1927: smart_str_appendl(&anonymous, "anonymous", sizeof("anonymous")-1);
1928: smart_str_append_long(&anonymous, zend_hash_num_elements(sdl->types));
1929: smart_str_0(&anonymous);
1930: dummy_type->name = anonymous.c;
1931: }
1932: dummy_type->namens = estrdup((char*)tns->children->content);
1933: schema_simpleType(sdl, tns, trav, dummy_type);
1934: newAttr->encode = dummy_type->encode;
1935: delete_type(&dummy_type);
1936: trav = trav->next;
1937: }
1938: }
1939: if (trav != NULL) {
1940: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attribute", trav->name);
1941: }
1942: return TRUE;
1943: }
1944:
1945: static int schema_attributeGroup(sdlPtr sdl, xmlAttrPtr tns, xmlNodePtr attrGroup, sdlTypePtr cur_type, sdlCtx *ctx)
1946: {
1947: xmlNodePtr trav;
1948: xmlAttrPtr name, ref = NULL;
1949:
1950:
1951: name = get_attribute(attrGroup->properties, "name");
1952: if (name == NULL) {
1953: name = ref = get_attribute(attrGroup->properties, "ref");
1954: }
1955: if (name) {
1956: if (cur_type == NULL) {
1957: xmlAttrPtr ns;
1958: sdlTypePtr newType;
1959: smart_str key = {0};
1960:
1961: ns = get_attribute(attrGroup->properties, "targetNamespace");
1962: if (ns == NULL) {
1963: ns = tns;
1964: }
1965: newType = emalloc(sizeof(sdlType));
1966: memset(newType, 0, sizeof(sdlType));
1967: newType->name = estrdup((char*)name->children->content);
1968: newType->namens = estrdup((char*)ns->children->content);
1969:
1970: smart_str_appends(&key, newType->namens);
1971: smart_str_appendc(&key, ':');
1972: smart_str_appends(&key, newType->name);
1973: smart_str_0(&key);
1974:
1975: if (zend_hash_add(ctx->attributeGroups, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), NULL) != SUCCESS) {
1976: soap_error1(E_ERROR, "Parsing Schema: attributeGroup '%s' already defined", key.c);
1977: }
1978: cur_type = newType;
1979: smart_str_free(&key);
1980: } else if (ref) {
1981: sdlAttributePtr newAttr;
1982: char *group_name, *ns;
1983: smart_str key = {0};
1984: xmlNsPtr nsptr;
1985:
1986: if (cur_type->attributes == NULL) {
1987: cur_type->attributes = emalloc(sizeof(HashTable));
1988: zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 0);
1989: }
1990: newAttr = emalloc(sizeof(sdlAttribute));
1991: memset(newAttr, 0, sizeof(sdlAttribute));
1992:
1993: parse_namespace(ref->children->content, &group_name, &ns);
1994: nsptr = xmlSearchNs(attrGroup->doc, attrGroup, BAD_CAST(ns));
1995: if (nsptr != NULL) {
1996: smart_str_appends(&key, (char*)nsptr->href);
1997: }
1998: smart_str_appendc(&key, ':');
1999: smart_str_appends(&key, group_name);
2000: smart_str_0(&key);
2001: newAttr->ref = estrdup(key.c);
2002: if (group_name) {efree(group_name);}
2003: if (ns) {efree(ns);}
2004: smart_str_free(&key);
2005:
2006: zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
2007: cur_type = NULL;
2008: }
2009: } else{
2010: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has no 'name' nor 'ref' attributes");
2011: }
2012:
2013: trav = attrGroup->children;
2014: if (trav != NULL && node_is_equal(trav, "annotation")) {
2015: /* TODO: <annotation> support */
2016: trav = trav->next;
2017: }
2018: while (trav != NULL) {
2019: if (node_is_equal(trav,"attribute")) {
2020: if (ref != NULL) {
2021: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
2022: }
2023: schema_attribute(sdl, tns, trav, cur_type, NULL);
2024: } else if (node_is_equal(trav,"attributeGroup")) {
2025: if (ref != NULL) {
2026: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
2027: }
2028: schema_attributeGroup(sdl, tns, trav, cur_type, NULL);
2029: } else if (node_is_equal(trav,"anyAttribute")) {
2030: if (ref != NULL) {
2031: soap_error0(E_ERROR, "Parsing Schema: attributeGroup has both 'ref' attribute and subattribute");
2032: }
2033: /* TODO: <anyAttribute> support */
2034: trav = trav->next;
2035: break;
2036: } else {
2037: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
2038: }
2039: trav = trav->next;
2040: }
2041: if (trav != NULL) {
2042: soap_error1(E_ERROR, "Parsing Schema: unexpected <%s> in attributeGroup", trav->name);
2043: }
2044: return TRUE;
2045: }
2046:
2047: static void copy_extra_attribute(void *attribute)
2048: {
2049: sdlExtraAttributePtr *attr = (sdlExtraAttributePtr*)attribute;
2050: sdlExtraAttributePtr new_attr;
2051:
2052: new_attr = emalloc(sizeof(sdlExtraAttribute));
2053: memcpy(new_attr, *attr, sizeof(sdlExtraAttribute));
2054: *attr = new_attr;
2055: if (new_attr->ns) {
2056: new_attr->ns = estrdup(new_attr->ns);
2057: }
2058: if (new_attr->val) {
2059: new_attr->val = estrdup(new_attr->val);
2060: }
2061: }
2062:
1.1.1.4 misho 2063: static void* schema_find_by_ref(HashTable *ht, char *ref)
2064: {
2065: void **tmp;
2066:
2067: if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
2068: return tmp;
2069: } else {
2070: ref = strrchr(ref, ':');
2071: if (ref) {
2072: if (zend_hash_find(ht, ref, strlen(ref)+1, (void**)&tmp) == SUCCESS) {
2073: return tmp;
2074: }
2075: }
2076: }
2077: return NULL;
2078: }
2079:
1.1 misho 2080: static void schema_attribute_fixup(sdlCtx *ctx, sdlAttributePtr attr)
2081: {
2082: sdlAttributePtr *tmp;
2083:
2084: if (attr->ref != NULL) {
2085: if (ctx->attributes != NULL) {
1.1.1.4 misho 2086: tmp = (sdlAttributePtr*)schema_find_by_ref(ctx->attributes, attr->ref);
2087: if (tmp) {
1.1 misho 2088: schema_attribute_fixup(ctx, *tmp);
2089: if ((*tmp)->name != NULL && attr->name == NULL) {
2090: attr->name = estrdup((*tmp)->name);
2091: }
2092: if ((*tmp)->namens != NULL && attr->namens == NULL) {
2093: attr->namens = estrdup((*tmp)->namens);
2094: }
2095: if ((*tmp)->def != NULL && attr->def == NULL) {
2096: attr->def = estrdup((*tmp)->def);
2097: }
2098: if ((*tmp)->fixed != NULL && attr->fixed == NULL) {
2099: attr->fixed = estrdup((*tmp)->fixed);
2100: }
2101: if (attr->form == XSD_FORM_DEFAULT) {
2102: attr->form = (*tmp)->form;
2103: }
2104: if (attr->use == XSD_USE_DEFAULT) {
2105: attr->use = (*tmp)->use;
2106: }
2107: if ((*tmp)->extraAttributes != NULL) {
2108: xmlNodePtr node;
2109:
2110: attr->extraAttributes = emalloc(sizeof(HashTable));
2111: zend_hash_init(attr->extraAttributes, zend_hash_num_elements((*tmp)->extraAttributes), NULL, delete_extra_attribute, 0);
2112: zend_hash_copy(attr->extraAttributes, (*tmp)->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
2113: }
2114: attr->encode = (*tmp)->encode;
2115: }
2116: }
2117: if (attr->name == NULL && attr->ref != NULL) {
2118: char *name = strrchr(attr->ref, ':');
2119: if (name) {
2120: attr->name = estrdup(name+1);
2121: } else{
2122: attr->name = estrdup(attr->ref);
2123: }
2124: }
2125: efree(attr->ref);
2126: attr->ref = NULL;
2127: }
2128: }
2129:
2130: static void schema_attributegroup_fixup(sdlCtx *ctx, sdlAttributePtr attr, HashTable *ht)
2131: {
2132: sdlTypePtr *tmp;
2133: sdlAttributePtr *tmp_attr;
2134:
2135: if (attr->ref != NULL) {
2136: if (ctx->attributeGroups != NULL) {
1.1.1.4 misho 2137: tmp = (sdlTypePtr*)schema_find_by_ref(ctx->attributeGroups, attr->ref);
2138: if (tmp) {
1.1 misho 2139: if ((*tmp)->attributes) {
2140: zend_hash_internal_pointer_reset((*tmp)->attributes);
2141: while (zend_hash_get_current_data((*tmp)->attributes,(void**)&tmp_attr) == SUCCESS) {
2142: if (zend_hash_get_current_key_type((*tmp)->attributes) == HASH_KEY_IS_STRING) {
2143: char* key;
2144: uint key_len;
2145: sdlAttributePtr newAttr;
2146:
2147: schema_attribute_fixup(ctx,*tmp_attr);
2148:
2149: newAttr = emalloc(sizeof(sdlAttribute));
2150: memcpy(newAttr, *tmp_attr, sizeof(sdlAttribute));
2151: if (newAttr->def) {newAttr->def = estrdup(newAttr->def);}
2152: if (newAttr->fixed) {newAttr->fixed = estrdup(newAttr->fixed);}
2153: if (newAttr->namens) {newAttr->namens = estrdup(newAttr->namens);}
2154: if (newAttr->name) {newAttr->name = estrdup(newAttr->name);}
2155: if (newAttr->extraAttributes) {
2156: xmlNodePtr node;
2157: HashTable *ht = emalloc(sizeof(HashTable));
2158: zend_hash_init(ht, zend_hash_num_elements(newAttr->extraAttributes), NULL, delete_extra_attribute, 0);
2159: zend_hash_copy(ht, newAttr->extraAttributes, copy_extra_attribute, &node, sizeof(xmlNodePtr));
2160: newAttr->extraAttributes = ht;
2161: }
2162:
2163: zend_hash_get_current_key_ex((*tmp)->attributes, &key, &key_len, NULL, 0, NULL);
2164: zend_hash_add(ht, key, key_len, &newAttr, sizeof(sdlAttributePtr), NULL);
2165:
2166: zend_hash_move_forward((*tmp)->attributes);
2167: } else {
2168: ulong index;
2169:
2170: schema_attributegroup_fixup(ctx,*tmp_attr, ht);
2171: zend_hash_get_current_key((*tmp)->attributes, NULL, &index, 0);
2172: zend_hash_index_del((*tmp)->attributes, index);
2173: }
2174: }
2175: }
2176: }
2177: }
2178: efree(attr->ref);
2179: attr->ref = NULL;
2180: }
2181: }
2182:
2183: static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
2184: {
2185: switch (model->kind) {
2186: case XSD_CONTENT_GROUP_REF: {
2187: sdlTypePtr *tmp;
2188:
2189: if (ctx->sdl->groups && zend_hash_find(ctx->sdl->groups, model->u.group_ref, strlen(model->u.group_ref)+1, (void**)&tmp) == SUCCESS) {
2190: schema_type_fixup(ctx,*tmp);
2191: efree(model->u.group_ref);
2192: model->kind = XSD_CONTENT_GROUP;
2193: model->u.group = (*tmp);
2194: } else {
1.1.1.4 misho 2195: soap_error1(E_ERROR, "Parsing Schema: unresolved group 'ref' attribute '%s'", model->u.group_ref);
1.1 misho 2196: }
2197: break;
2198: }
2199: case XSD_CONTENT_CHOICE: {
2200: if (model->max_occurs != 1) {
2201: HashPosition pos;
2202: sdlContentModelPtr *tmp;
2203:
2204: zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
2205: while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
2206: (*tmp)->min_occurs = 0;
2207: (*tmp)->max_occurs = model->max_occurs;
2208: zend_hash_move_forward_ex(model->u.content, &pos);
2209: }
2210:
2211: model->kind = XSD_CONTENT_ALL;
2212: model->min_occurs = 1;
2213: model->max_occurs = 1;
2214: }
2215: }
2216: case XSD_CONTENT_SEQUENCE:
2217: case XSD_CONTENT_ALL: {
2218: sdlContentModelPtr *tmp;
2219:
2220: zend_hash_internal_pointer_reset(model->u.content);
2221: while (zend_hash_get_current_data(model->u.content, (void**)&tmp) == SUCCESS) {
2222: schema_content_model_fixup(ctx, *tmp);
2223: zend_hash_move_forward(model->u.content);
2224: }
2225: break;
2226: }
2227: default:
2228: break;
2229: }
2230: }
2231:
2232: static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type)
2233: {
2234: sdlTypePtr *tmp;
2235: sdlAttributePtr *attr;
2236:
2237: if (type->ref != NULL) {
2238: if (ctx->sdl->elements != NULL) {
1.1.1.4 misho 2239: tmp = (sdlTypePtr*)schema_find_by_ref(ctx->sdl->elements, type->ref);
2240: if (tmp) {
1.1 misho 2241: type->kind = (*tmp)->kind;
2242: type->encode = (*tmp)->encode;
2243: if ((*tmp)->nillable) {
2244: type->nillable = 1;
2245: }
2246: if ((*tmp)->fixed) {
2247: type->fixed = estrdup((*tmp)->fixed);
2248: }
2249: if ((*tmp)->def) {
2250: type->def = estrdup((*tmp)->def);
2251: }
2252: type->form = (*tmp)->form;
2253: } else if (strcmp(type->ref, SCHEMA_NAMESPACE ":schema") == 0) {
2254: type->encode = get_conversion(XSD_ANYXML);
2255: } else {
1.1.1.4 misho 2256: soap_error1(E_ERROR, "Parsing Schema: unresolved element 'ref' attribute '%s'", type->ref);
1.1 misho 2257: }
2258: }
2259: efree(type->ref);
2260: type->ref = NULL;
2261: }
2262: if (type->elements) {
2263: zend_hash_internal_pointer_reset(type->elements);
2264: while (zend_hash_get_current_data(type->elements,(void**)&tmp) == SUCCESS) {
2265: schema_type_fixup(ctx,*tmp);
2266: zend_hash_move_forward(type->elements);
2267: }
2268: }
2269: if (type->model) {
2270: schema_content_model_fixup(ctx, type->model);
2271: }
2272: if (type->attributes) {
2273: zend_hash_internal_pointer_reset(type->attributes);
2274: while (zend_hash_get_current_data(type->attributes,(void**)&attr) == SUCCESS) {
2275: if (zend_hash_get_current_key_type(type->attributes) == HASH_KEY_IS_STRING) {
2276: schema_attribute_fixup(ctx,*attr);
2277: zend_hash_move_forward(type->attributes);
2278: } else {
2279: ulong index;
2280:
2281: schema_attributegroup_fixup(ctx,*attr,type->attributes);
2282: zend_hash_get_current_key(type->attributes, NULL, &index, 0);
2283: zend_hash_index_del(type->attributes, index);
2284: }
2285: }
2286: }
2287: }
2288:
2289: void schema_pass2(sdlCtx *ctx)
2290: {
2291: sdlPtr sdl = ctx->sdl;
2292: sdlAttributePtr *attr;
2293: sdlTypePtr *type;
2294:
2295: if (ctx->attributes) {
2296: zend_hash_internal_pointer_reset(ctx->attributes);
2297: while (zend_hash_get_current_data(ctx->attributes,(void**)&attr) == SUCCESS) {
2298: schema_attribute_fixup(ctx,*attr);
2299: zend_hash_move_forward(ctx->attributes);
2300: }
2301: }
2302: if (ctx->attributeGroups) {
2303: zend_hash_internal_pointer_reset(ctx->attributeGroups);
2304: while (zend_hash_get_current_data(ctx->attributeGroups,(void**)&type) == SUCCESS) {
2305: schema_type_fixup(ctx,*type);
2306: zend_hash_move_forward(ctx->attributeGroups);
2307: }
2308: }
2309: if (sdl->elements) {
2310: zend_hash_internal_pointer_reset(sdl->elements);
2311: while (zend_hash_get_current_data(sdl->elements,(void**)&type) == SUCCESS) {
2312: schema_type_fixup(ctx,*type);
2313: zend_hash_move_forward(sdl->elements);
2314: }
2315: }
2316: if (sdl->groups) {
2317: zend_hash_internal_pointer_reset(sdl->groups);
2318: while (zend_hash_get_current_data(sdl->groups,(void**)&type) == SUCCESS) {
2319: schema_type_fixup(ctx,*type);
2320: zend_hash_move_forward(sdl->groups);
2321: }
2322: }
2323: if (sdl->types) {
2324: zend_hash_internal_pointer_reset(sdl->types);
2325: while (zend_hash_get_current_data(sdl->types,(void**)&type) == SUCCESS) {
2326: schema_type_fixup(ctx,*type);
2327: zend_hash_move_forward(sdl->types);
2328: }
2329: }
2330: if (ctx->attributes) {
2331: zend_hash_destroy(ctx->attributes);
2332: efree(ctx->attributes);
2333: }
2334: if (ctx->attributeGroups) {
2335: zend_hash_destroy(ctx->attributeGroups);
2336: efree(ctx->attributeGroups);
2337: }
2338: }
2339:
2340: void delete_model(void *handle)
2341: {
2342: sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
2343: switch (tmp->kind) {
2344: case XSD_CONTENT_ELEMENT:
2345: case XSD_CONTENT_GROUP:
2346: break;
2347: case XSD_CONTENT_SEQUENCE:
2348: case XSD_CONTENT_ALL:
2349: case XSD_CONTENT_CHOICE:
2350: zend_hash_destroy(tmp->u.content);
2351: efree(tmp->u.content);
2352: break;
2353: case XSD_CONTENT_GROUP_REF:
2354: efree(tmp->u.group_ref);
2355: break;
2356: default:
2357: break;
2358: }
2359: efree(tmp);
2360: }
2361:
2362: void delete_model_persistent(void *handle)
2363: {
2364: sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
2365: switch (tmp->kind) {
2366: case XSD_CONTENT_ELEMENT:
2367: case XSD_CONTENT_GROUP:
2368: break;
2369: case XSD_CONTENT_SEQUENCE:
2370: case XSD_CONTENT_ALL:
2371: case XSD_CONTENT_CHOICE:
2372: zend_hash_destroy(tmp->u.content);
2373: free(tmp->u.content);
2374: break;
2375: case XSD_CONTENT_GROUP_REF:
2376: free(tmp->u.group_ref);
2377: break;
2378: default:
2379: break;
2380: }
2381: free(tmp);
2382: }
2383:
2384: void delete_type(void *data)
2385: {
2386: sdlTypePtr type = *((sdlTypePtr*)data);
2387:
2388: if (type->name) {
2389: efree(type->name);
2390: }
2391: if (type->namens) {
2392: efree(type->namens);
2393: }
2394: if (type->def) {
2395: efree(type->def);
2396: }
2397: if (type->fixed) {
2398: efree(type->fixed);
2399: }
2400: if (type->elements) {
2401: zend_hash_destroy(type->elements);
2402: efree(type->elements);
2403: }
2404: if (type->attributes) {
2405: zend_hash_destroy(type->attributes);
2406: efree(type->attributes);
2407: }
2408: if (type->model) {
2409: delete_model((void**)&type->model);
2410: }
2411: if (type->restrictions) {
2412: delete_restriction_var_int(&type->restrictions->minExclusive);
2413: delete_restriction_var_int(&type->restrictions->minInclusive);
2414: delete_restriction_var_int(&type->restrictions->maxExclusive);
2415: delete_restriction_var_int(&type->restrictions->maxInclusive);
2416: delete_restriction_var_int(&type->restrictions->totalDigits);
2417: delete_restriction_var_int(&type->restrictions->fractionDigits);
2418: delete_restriction_var_int(&type->restrictions->length);
2419: delete_restriction_var_int(&type->restrictions->minLength);
2420: delete_restriction_var_int(&type->restrictions->maxLength);
2421: delete_restriction_var_char(&type->restrictions->whiteSpace);
2422: delete_restriction_var_char(&type->restrictions->pattern);
2423: if (type->restrictions->enumeration) {
2424: zend_hash_destroy(type->restrictions->enumeration);
2425: efree(type->restrictions->enumeration);
2426: }
2427: efree(type->restrictions);
2428: }
2429: efree(type);
2430: }
2431:
2432: void delete_type_persistent(void *data)
2433: {
2434: sdlTypePtr type = *((sdlTypePtr*)data);
2435: if (type->name) {
2436: free(type->name);
2437: }
2438: if (type->namens) {
2439: free(type->namens);
2440: }
2441: if (type->def) {
2442: free(type->def);
2443: }
2444: if (type->fixed) {
2445: free(type->fixed);
2446: }
2447: if (type->elements) {
2448: zend_hash_destroy(type->elements);
2449: free(type->elements);
2450: }
2451: if (type->attributes) {
2452: zend_hash_destroy(type->attributes);
2453: free(type->attributes);
2454: }
2455: if (type->model) {
2456: delete_model_persistent((void**)&type->model);
2457: }
2458: if (type->restrictions) {
2459: delete_restriction_var_int_persistent(&type->restrictions->minExclusive);
2460: delete_restriction_var_int_persistent(&type->restrictions->minInclusive);
2461: delete_restriction_var_int_persistent(&type->restrictions->maxExclusive);
2462: delete_restriction_var_int_persistent(&type->restrictions->maxInclusive);
2463: delete_restriction_var_int_persistent(&type->restrictions->totalDigits);
2464: delete_restriction_var_int_persistent(&type->restrictions->fractionDigits);
2465: delete_restriction_var_int_persistent(&type->restrictions->length);
2466: delete_restriction_var_int_persistent(&type->restrictions->minLength);
2467: delete_restriction_var_int_persistent(&type->restrictions->maxLength);
2468: delete_restriction_var_char_persistent(&type->restrictions->whiteSpace);
2469: delete_restriction_var_char_persistent(&type->restrictions->pattern);
2470: if (type->restrictions->enumeration) {
2471: zend_hash_destroy(type->restrictions->enumeration);
2472: free(type->restrictions->enumeration);
2473: }
2474: free(type->restrictions);
2475: }
2476: free(type);
2477: }
2478:
2479: void delete_extra_attribute(void *attribute)
2480: {
2481: sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
2482:
2483: if (attr->ns) {
2484: efree(attr->ns);
2485: }
2486: if (attr->val) {
2487: efree(attr->val);
2488: }
2489: efree(attr);
2490: }
2491:
2492: void delete_extra_attribute_persistent(void *attribute)
2493: {
2494: sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
2495:
2496: if (attr->ns) {
2497: free(attr->ns);
2498: }
2499: if (attr->val) {
2500: free(attr->val);
2501: }
2502: free(attr);
2503: }
2504:
2505: void delete_attribute(void *attribute)
2506: {
2507: sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
2508:
2509: if (attr->def) {
2510: efree(attr->def);
2511: }
2512: if (attr->fixed) {
2513: efree(attr->fixed);
2514: }
2515: if (attr->name) {
2516: efree(attr->name);
2517: }
2518: if (attr->namens) {
2519: efree(attr->namens);
2520: }
2521: if (attr->ref) {
2522: efree(attr->ref);
2523: }
2524: if (attr->extraAttributes) {
2525: zend_hash_destroy(attr->extraAttributes);
2526: efree(attr->extraAttributes);
2527: }
2528: efree(attr);
2529: }
2530:
2531: void delete_attribute_persistent(void *attribute)
2532: {
2533: sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
2534:
2535: if (attr->def) {
2536: free(attr->def);
2537: }
2538: if (attr->fixed) {
2539: free(attr->fixed);
2540: }
2541: if (attr->name) {
2542: free(attr->name);
2543: }
2544: if (attr->namens) {
2545: free(attr->namens);
2546: }
2547: if (attr->ref) {
2548: free(attr->ref);
2549: }
2550: if (attr->extraAttributes) {
2551: zend_hash_destroy(attr->extraAttributes);
2552: free(attr->extraAttributes);
2553: }
2554: free(attr);
2555: }
2556:
2557: void delete_restriction_var_int(void *rvi)
2558: {
2559: sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
2560: if (ptr) {
2561: efree(ptr);
2562: }
2563: }
2564:
2565: void delete_restriction_var_int_persistent(void *rvi)
2566: {
2567: sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
2568: if (ptr) {
2569: free(ptr);
2570: }
2571: }
2572:
2573: void delete_restriction_var_char(void *srvc)
2574: {
2575: sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
2576: if (ptr) {
2577: if (ptr->value) {
2578: efree(ptr->value);
2579: }
2580: efree(ptr);
2581: }
2582: }
2583:
2584: void delete_restriction_var_char_persistent(void *srvc)
2585: {
2586: sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
2587: if (ptr) {
2588: if (ptr->value) {
2589: free(ptr->value);
2590: }
2591: free(ptr);
2592: }
2593: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>