You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1061 lines
31 KiB

  1. #include "php_soap.h"
  2. static int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type);
  3. static int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type);
  4. static int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type);
  5. static int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type);
  6. static int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type);
  7. static int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type);
  8. static int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type);
  9. static int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type);
  10. static int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type);
  11. static int schema_extension_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
  12. static int schema_extension_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
  13. static int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
  14. static int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type);
  15. static int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type);
  16. static int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type);
  17. static int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type);
  18. static int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type);
  19. static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr);
  20. static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr);
  21. /*
  22. 2.6.1 xsi:type
  23. 2.6.2 xsi:nil
  24. 2.6.3 xsi:schemaLocation, xsi:noNamespaceSchemaLocation
  25. */
  26. /*
  27. <schema
  28. attributeFormDefault = (qualified | unqualified) : unqualified
  29. blockDefault = (#all | List of (extension | restriction | substitution)) : ''
  30. elementFormDefault = (qualified | unqualified) : unqualified
  31. finalDefault = (#all | List of (extension | restriction)) : ''
  32. id = ID
  33. targetNamespace = anyURI
  34. version = token
  35. xml:lang = language
  36. {any attributes with non-schema namespace . . .}>
  37. Content: ((include | import | redefine | annotation)*, (((simpleType | complexType | group | attributeGroup) | element | attribute | notation), annotation*)*)
  38. </schema>
  39. */
  40. int load_schema(sdlPtr *sdl,xmlNodePtr schema)
  41. {
  42. xmlNodePtr trav, element, compType, simpleType, attribute;
  43. xmlAttrPtr tns;
  44. if(!(*sdl)->types) {
  45. (*sdl)->types = malloc(sizeof(HashTable));
  46. zend_hash_init((*sdl)->types, 0, NULL, delete_type, 1);
  47. }
  48. tns = get_attribute(schema->properties, "targetNamespace");
  49. trav = schema->children;
  50. FOREACHNODE(trav,"complexType",compType) {
  51. schema_complexType(sdl, tns, compType, NULL);
  52. }
  53. ENDFOREACH(trav);
  54. trav = schema->children;
  55. FOREACHNODE(trav,"simpleType",simpleType) {
  56. schema_simpleType(sdl, tns, simpleType, NULL);
  57. }
  58. ENDFOREACH(trav);
  59. trav = schema->children;
  60. FOREACHNODE(trav,"element",element) {
  61. schema_element(sdl, tns, element, NULL);
  62. }
  63. ENDFOREACH(trav);
  64. trav = schema->children;
  65. FOREACHNODE(trav, "attribute", attribute) {
  66. schema_attribute(sdl, tns, attribute, NULL);
  67. }
  68. ENDFOREACH(trav);
  69. return FALSE;
  70. }
  71. /*
  72. <simpleType
  73. final = (#all | (list | union | restriction))
  74. id = ID
  75. name = NCName
  76. {any attributes with non-schema namespace . . .}>
  77. Content: (annotation?, (restriction | list | union))
  78. </simpleType>
  79. */
  80. static int schema_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpleType, sdlTypePtr cur_type)
  81. {
  82. xmlNodePtr content;
  83. xmlAttrPtr name, ns;
  84. ns = get_attribute(simpleType->properties, "targetNamespace");
  85. if(ns == NULL) {
  86. ns = tsn;
  87. }
  88. name = get_attribute(simpleType->properties, "name");
  89. if(name != NULL) {
  90. HashTable *ht;
  91. smart_str key = {0};
  92. sdlTypePtr newType, *ptr;
  93. newType = malloc(sizeof(sdlType));
  94. memset(newType, 0, sizeof(sdlType));
  95. newType->name = strdup(name->children->content);
  96. newType->namens = strdup(ns->children->content);
  97. if(cur_type == NULL) {
  98. ht = (*sdl)->types;
  99. smart_str_appends(&key, newType->namens);
  100. smart_str_appendc(&key, ':');
  101. smart_str_appends(&key, newType->name);
  102. smart_str_0(&key);
  103. } else {
  104. if(cur_type->elements == NULL) {
  105. cur_type->elements = malloc(sizeof(HashTable));
  106. zend_hash_init(cur_type->elements, 0, NULL, delete_type, 1);
  107. }
  108. ht = cur_type->elements;
  109. smart_str_appends(&key, cur_type->name);
  110. }
  111. zend_hash_add(ht, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&ptr);
  112. cur_type = (*ptr);
  113. create_encoder((*sdl), cur_type, ns->children->content, name->children->content);
  114. smart_str_free(&key);
  115. }
  116. content = get_node(simpleType->children, "restriction");
  117. if(content != NULL) {
  118. schema_restriction_simpleType(sdl, tsn, content, cur_type);
  119. return TRUE;
  120. }
  121. content = get_node(simpleType->children, "list");
  122. if(content != NULL) {
  123. schema_list(sdl, tsn, content, cur_type);
  124. return TRUE;
  125. }
  126. content = get_node(simpleType->children, "union");
  127. if(content != NULL) {
  128. schema_union(sdl, tsn, content, cur_type);
  129. return TRUE;
  130. }
  131. return FALSE;
  132. }
  133. /*
  134. <list
  135. id = ID
  136. itemType = QName
  137. {any attributes with non-schema namespace . . .}>
  138. Content: (annotation?, (simpleType?))
  139. </list>
  140. */
  141. static int schema_list(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr listType, sdlTypePtr cur_type)
  142. {
  143. return TRUE;
  144. }
  145. /*
  146. <union
  147. id = ID
  148. memberTypes = List of QName
  149. {any attributes with non-schema namespace . . .}>
  150. Content: (annotation?, (simpleType*))
  151. </union>
  152. */
  153. static int schema_union(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr unionType, sdlTypePtr cur_type)
  154. {
  155. return TRUE;
  156. }
  157. /*
  158. <simpleContent
  159. id = ID
  160. {any attributes with non-schema namespace . . .}>
  161. Content: (annotation?, (restriction | extension))
  162. </simpleContent>
  163. */
  164. static int schema_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr simpCompType, sdlTypePtr cur_type)
  165. {
  166. xmlNodePtr content;
  167. content = get_node(simpCompType->children, "restriction");
  168. if(content != NULL) {
  169. schema_restriction_simpleContent(sdl, tsn, content, cur_type);
  170. return TRUE;
  171. }
  172. content = get_node(simpCompType->children, "extension");
  173. if(content != NULL) {
  174. schema_extension_simpleContent(sdl, tsn, content, cur_type);
  175. // php_error(E_ERROR, "Error parsing schema (doesn't support extensions on simpleContent)");
  176. return TRUE;
  177. }
  178. php_error(E_ERROR, "Error parsing schema (simpleContent)");
  179. return FALSE;
  180. }
  181. /*
  182. <restriction
  183. base = QName
  184. id = ID
  185. {any attributes with non-schema namespace . . .}>
  186. Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))
  187. </restriction>
  188. */
  189. static int schema_restriction_simpleType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type)
  190. {
  191. xmlNodePtr content, trav;
  192. xmlAttrPtr base;
  193. content = get_node(restType->children, "simpleType");
  194. if(content != NULL) {
  195. schema_simpleType(sdl, tsn, content, cur_type);
  196. return TRUE;
  197. }
  198. base = get_attribute(restType->properties, "base");
  199. if(base != NULL) {
  200. char *type, *ns;
  201. xmlNsPtr nsptr;
  202. parse_namespace(base->children->content, &type, &ns);
  203. nsptr = xmlSearchNs(restType->doc, restType, ns);
  204. if(nsptr != NULL) {
  205. cur_type->encode = get_encoder((*sdl), (char *)nsptr->href, type);
  206. }
  207. if(type) {efree(type);}
  208. if(ns) {efree(ns);}
  209. }
  210. if(cur_type->restrictions == NULL) {
  211. cur_type->restrictions = malloc(sizeof(sdlRestrictions));
  212. memset(cur_type->restrictions, 0, sizeof(sdlRestrictions));
  213. }
  214. trav = restType->children;
  215. while (trav != NULL) {
  216. if(trav->type == XML_ELEMENT_NODE) {
  217. if(!strcmp(trav->name, "minExclusive")) {
  218. schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive);
  219. } else if(!strcmp(trav->name, "minInclusive")) {
  220. schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive);
  221. } else if(!strcmp(trav->name, "maxExclusive")) {
  222. schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive);
  223. } else if(!strcmp(trav->name, "maxInclusive")) {
  224. schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive);
  225. } else if(!strcmp(trav->name, "totalDigits")) {
  226. schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits);
  227. } else if(!strcmp(trav->name, "fractionDigits")) {
  228. schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits);
  229. } else if(!strcmp(trav->name, "length")) {
  230. schema_restriction_var_int(trav, &cur_type->restrictions->length);
  231. } else if(!strcmp(trav->name, "minLength")) {
  232. schema_restriction_var_int(trav, &cur_type->restrictions->minLength);
  233. } else if(!strcmp(trav->name, "maxLength")) {
  234. schema_restriction_var_int(trav, &cur_type->restrictions->maxLength);
  235. } else if(!strcmp(trav->name, "whiteSpace")) {
  236. schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace);
  237. } else if(!strcmp(trav->name, "pattern")) {
  238. schema_restriction_var_char(trav, &cur_type->restrictions->pattern);
  239. } else if(!strcmp(trav->name, "enumeration")) {
  240. sdlRestrictionCharPtr enumval = NULL;
  241. schema_restriction_var_char(trav, &enumval);
  242. if(cur_type->restrictions->enumeration == NULL) {
  243. cur_type->restrictions->enumeration = malloc(sizeof(HashTable));
  244. zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_schema_restriction_var_char, 1);
  245. }
  246. zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL);
  247. }
  248. }
  249. trav = trav->next;
  250. }
  251. return TRUE;
  252. }
  253. /*
  254. <restriction
  255. base = QName
  256. id = ID
  257. {any attributes with non-schema namespace . . .}>
  258. Content: (annotation?, (group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))
  259. </restriction>
  260. */
  261. static int schema_restriction_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type)
  262. {
  263. xmlAttrPtr base;
  264. xmlNodePtr trav;
  265. base = get_attribute(restType->properties, "base");
  266. if(base != NULL) {
  267. char *type, *ns;
  268. xmlNsPtr nsptr;
  269. parse_namespace(base->children->content, &type, &ns);
  270. nsptr = xmlSearchNs(restType->doc, restType, ns);
  271. if(nsptr != NULL) {
  272. cur_type->encode = get_encoder((*sdl), (char *)nsptr->href, type);
  273. }
  274. if(type) {efree(type);}
  275. if(ns) {efree(ns);}
  276. }
  277. trav = restType->children;
  278. while (trav != NULL) {
  279. if(trav->type == XML_ELEMENT_NODE) {
  280. if(!strcmp(trav->name, "group")) {
  281. schema_group(sdl, tsn, trav, cur_type);
  282. return TRUE;
  283. } else if(!strcmp(trav->name, "all")) {
  284. schema_all(sdl, tsn, trav, cur_type);
  285. return TRUE;
  286. } else if(!strcmp(trav->name, "choice")) {
  287. schema_choice(sdl, tsn, trav, cur_type);
  288. return TRUE;
  289. } else if(!strcmp(trav->name, "sequence")) {
  290. schema_sequence(sdl, tsn, trav, cur_type);
  291. return TRUE;
  292. } else if(!strcmp(trav->name, "attribute")) {
  293. schema_attribute(sdl, tsn, trav, cur_type);
  294. }
  295. }
  296. trav = trav->next;
  297. }
  298. return TRUE;
  299. }
  300. /*
  301. <restriction
  302. base = QName
  303. id = ID
  304. {any attributes with non-schema Namespace . . .}>
  305. Content: (annotation?, (simpleType?, (minExclusive | minInclusive | maxExclusive | maxInclusive | totalDigits | fractionDigits | length | minLength | maxLength | enumeration | whiteSpace | pattern)*))
  306. </restriction>
  307. */
  308. static int schema_restriction_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr restType, sdlTypePtr cur_type)
  309. {
  310. xmlNodePtr content, trav;
  311. xmlAttrPtr base;
  312. base = get_attribute(restType->properties, "base");
  313. if(base != NULL)
  314. cur_type->encode = get_encoder_from_prefix((*sdl), restType, base->children->content);
  315. content = get_node(restType->children, "simpleType");
  316. if(content != NULL) {
  317. schema_simpleType(sdl, tsn, content, cur_type);
  318. return TRUE;
  319. }
  320. if(cur_type->restrictions == NULL) {
  321. cur_type->restrictions = malloc(sizeof(sdlRestrictions));
  322. memset(cur_type->restrictions, 0, sizeof(sdlRestrictions));
  323. }
  324. trav = restType->children;
  325. while (trav != NULL) {
  326. if(trav->type == XML_ELEMENT_NODE) {
  327. if(!strcmp(trav->name, "minExclusive")) {
  328. schema_restriction_var_int(trav, &cur_type->restrictions->minExclusive);
  329. } else if(!strcmp(trav->name, "minInclusive")) {
  330. schema_restriction_var_int(trav, &cur_type->restrictions->minInclusive);
  331. } else if(!strcmp(trav->name, "maxExclusive")) {
  332. schema_restriction_var_int(trav, &cur_type->restrictions->maxExclusive);
  333. } else if(!strcmp(trav->name, "maxInclusive")) {
  334. schema_restriction_var_int(trav, &cur_type->restrictions->maxInclusive);
  335. } else if(!strcmp(trav->name, "totalDigits")) {
  336. schema_restriction_var_int(trav, &cur_type->restrictions->totalDigits);
  337. } else if(!strcmp(trav->name, "fractionDigits")) {
  338. schema_restriction_var_int(trav, &cur_type->restrictions->fractionDigits);
  339. } else if(!strcmp(trav->name, "length")) {
  340. schema_restriction_var_int(trav, &cur_type->restrictions->length);
  341. } else if(!strcmp(trav->name, "minLength")) {
  342. schema_restriction_var_int(trav, &cur_type->restrictions->minLength);
  343. } else if(!strcmp(trav->name, "maxLength")) {
  344. schema_restriction_var_int(trav, &cur_type->restrictions->maxLength);
  345. } else if(!strcmp(trav->name, "whiteSpace")) {
  346. schema_restriction_var_char(trav, &cur_type->restrictions->whiteSpace);
  347. } else if(!strcmp(trav->name, "pattern")) {
  348. schema_restriction_var_char(trav, &cur_type->restrictions->pattern);
  349. } else if(!strcmp(trav->name, "enumeration")) {
  350. sdlRestrictionCharPtr enumval = NULL;
  351. schema_restriction_var_char(trav, &enumval);
  352. if(cur_type->restrictions->enumeration == NULL) {
  353. cur_type->restrictions->enumeration = malloc(sizeof(HashTable));
  354. zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_schema_restriction_var_char, 1);
  355. }
  356. zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL);
  357. // zend_hash_next_index_insert(cur_type->restrictions->enumeration, &enumval, sizeof(sdlRestrictionCharPtr), NULL);
  358. }
  359. }
  360. trav = trav->next;
  361. }
  362. return TRUE;
  363. }
  364. static int schema_restriction_var_int(xmlNodePtr val, sdlRestrictionIntPtr *valptr)
  365. {
  366. xmlAttrPtr fixed, value, id;
  367. if((*valptr) == NULL) {
  368. (*valptr) = malloc(sizeof(sdlRestrictionInt));
  369. }
  370. memset((*valptr), 0, sizeof(sdlRestrictionInt));
  371. fixed = get_attribute(val->properties, "fixed");
  372. (*valptr)->fixed = FALSE;
  373. if(fixed != NULL) {
  374. if(!strcmp(fixed->children->content, "true") ||
  375. !strcmp(fixed->children->content, "1"))
  376. (*valptr)->fixed = TRUE;
  377. }
  378. id = get_attribute(val->properties, "id");
  379. if(id != NULL) {
  380. (*valptr)->id = strdup(id->children->content);
  381. }
  382. value = get_attribute(val->properties, "value");
  383. if(value == NULL) {
  384. php_error(E_ERROR, "Error parsing wsdl schema \"missing restriction value\"");
  385. }
  386. (*valptr)->value = atoi(value->children->content);
  387. return TRUE;
  388. }
  389. void delete_restriction_var_int(void *rvi)
  390. {
  391. sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
  392. if (ptr) {
  393. if (ptr->id) {
  394. free(ptr->id);
  395. }
  396. free(ptr);
  397. }
  398. }
  399. static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *valptr)
  400. {
  401. xmlAttrPtr fixed, value, id;
  402. if((*valptr) == NULL) {
  403. (*valptr) = malloc(sizeof(sdlRestrictionChar));
  404. }
  405. memset((*valptr), 0, sizeof(sdlRestrictionChar));
  406. fixed = get_attribute(val->properties, "fixed");
  407. (*valptr)->fixed = FALSE;
  408. if(fixed != NULL) {
  409. if(!strcmp(fixed->children->content, "true") ||
  410. !strcmp(fixed->children->content, "1")) {
  411. (*valptr)->fixed = TRUE;
  412. }
  413. }
  414. id = get_attribute(val->properties, "id");
  415. if(id != NULL) {
  416. (*valptr)->id = strdup(id->children->content);
  417. }
  418. value = get_attribute(val->properties, "value");
  419. if(value == NULL) {
  420. php_error(E_ERROR, "Error parsing wsdl schema \"missing restriction value\"");
  421. }
  422. (*valptr)->value = strdup(value->children->content);
  423. return TRUE;
  424. }
  425. void delete_schema_restriction_var_char(void *srvc)
  426. {
  427. sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
  428. if (ptr) {
  429. if(ptr->id) {
  430. free(ptr->id);
  431. }
  432. if(ptr->value) {
  433. free(ptr->value);
  434. }
  435. free(ptr);
  436. }
  437. }
  438. /*
  439. From simpleContent (not supported):
  440. <extension
  441. base = QName
  442. id = ID
  443. {any attributes with non-schema namespace . . .}>
  444. Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?))
  445. </extension>
  446. */
  447. static int schema_extension_simpleContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type)
  448. {
  449. return TRUE;
  450. }
  451. /*
  452. From complexContent:
  453. <extension
  454. base = QName
  455. id = ID
  456. {any attributes with non-schema namespace . . .}>
  457. Content: (annotation?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))
  458. </extension>
  459. */
  460. static int schema_extension_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type)
  461. {
  462. xmlNodePtr content;
  463. xmlAttrPtr base;
  464. base = get_attribute(extType->properties, "base");
  465. content = get_node(extType->children, "group");
  466. if(content != NULL) {
  467. schema_group(sdl, tsn, content, cur_type);
  468. return TRUE;
  469. }
  470. content = get_node(extType->children, "all");
  471. if(content != NULL) {
  472. schema_all(sdl, tsn, content, cur_type);
  473. return TRUE;
  474. }
  475. content = get_node(extType->children, "choice");
  476. if(content != NULL) {
  477. schema_choice(sdl, tsn, content, cur_type);
  478. return TRUE;
  479. }
  480. content = get_node(extType->children, "sequence");
  481. if(content != NULL) {
  482. schema_sequence(sdl, tsn, content, cur_type);
  483. return TRUE;
  484. }
  485. return FALSE;
  486. }
  487. /*
  488. <all
  489. id = ID
  490. maxOccurs = 1 : 1
  491. minOccurs = (0 | 1) : 1
  492. {any attributes with non-schema namespace . . .}>
  493. Content: (annotation?, element*)
  494. </all>
  495. */
  496. static int schema_all(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr all, sdlTypePtr cur_type)
  497. {
  498. xmlNodePtr element, trav;
  499. trav = all->children;
  500. FOREACHNODE(trav, "element", element) {
  501. schema_element(sdl, tsn, element, cur_type);
  502. }
  503. ENDFOREACH(trav);
  504. return TRUE;
  505. }
  506. /*
  507. <group
  508. name = NCName>
  509. Content: (annotation?, (all | choice | sequence))
  510. </group>
  511. */
  512. static int schema_group(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr groupType, sdlTypePtr cur_type)
  513. {
  514. xmlNodePtr content;
  515. xmlAttrPtr name;
  516. name = get_attribute(groupType->properties, "name");
  517. if(name != NULL) {
  518. }
  519. content = get_node(groupType->children, "all");
  520. if(content != NULL) {
  521. schema_all(sdl, tsn, content, cur_type);
  522. return TRUE;
  523. }
  524. content = get_node(groupType->children, "choice");
  525. if(content != NULL) {
  526. schema_choice(sdl, tsn, content, cur_type);
  527. return TRUE;
  528. }
  529. content = get_node(groupType->children, "sequence");
  530. if(content != NULL) {
  531. schema_sequence(sdl, tsn, content, cur_type);
  532. return TRUE;
  533. }
  534. return FALSE;
  535. }
  536. /*
  537. <choice
  538. id = ID
  539. maxOccurs = (nonNegativeInteger | unbounded) : 1
  540. minOccurs = nonNegativeInteger : 1
  541. {any attributes with non-schema namespace . . .}>
  542. Content: (annotation?, (element | group | choice | sequence | any)*)
  543. </choice>
  544. */
  545. static int schema_choice(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr choiceType, sdlTypePtr cur_type)
  546. {
  547. xmlNodePtr trav, data;
  548. /*
  549. cur_type->property_type = CHOICE;
  550. */
  551. trav = choiceType->children;
  552. FOREACHNODE(trav, "element", data) {
  553. schema_element(sdl, tsn, data, cur_type);
  554. }
  555. ENDFOREACH(trav);
  556. trav = choiceType->children;
  557. FOREACHNODE(trav, "group", data) {
  558. schema_group(sdl, tsn, data, cur_type);
  559. }
  560. ENDFOREACH(trav);
  561. trav = choiceType->children;
  562. FOREACHNODE(trav, "choice", data) {
  563. schema_choice(sdl, tsn, data, cur_type);
  564. }
  565. ENDFOREACH(trav);
  566. trav = choiceType->children;
  567. FOREACHNODE(trav, "sequence", data) {
  568. schema_sequence(sdl, tsn, data, cur_type);
  569. }
  570. ENDFOREACH(trav);
  571. trav = choiceType->children;
  572. FOREACHNODE(trav, "any", data) {
  573. schema_any(sdl, tsn, data, cur_type);
  574. }
  575. ENDFOREACH(trav);
  576. return TRUE;
  577. }
  578. /*
  579. <sequence
  580. id = ID
  581. maxOccurs = (nonNegativeInteger | unbounded) : 1
  582. minOccurs = nonNegativeInteger : 1
  583. {any attributes with non-schema namespace . . .}>
  584. Content: (annotation?, (element | group | choice | sequence | any)*)
  585. </sequence>
  586. */
  587. static int schema_sequence(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr seqType, sdlTypePtr cur_type)
  588. {
  589. xmlNodePtr trav;
  590. trav = seqType->children;
  591. while (trav != NULL) {
  592. if(trav->type == XML_ELEMENT_NODE) {
  593. if(!strcmp(trav->name, "element")) {
  594. schema_element(sdl, tsn, trav, cur_type);
  595. } else if(!strcmp(trav->name, "group")) {
  596. schema_group(sdl, tsn, trav, cur_type);
  597. } else if(!strcmp(trav->name, "choice")) {
  598. schema_choice(sdl, tsn, trav, cur_type);
  599. } else if(!strcmp(trav->name, "sequence")) {
  600. schema_sequence(sdl, tsn, trav, cur_type);
  601. } else if(!strcmp(trav->name, "any")) {
  602. schema_any(sdl, tsn, trav, cur_type);
  603. }
  604. }
  605. trav = trav->next;
  606. }
  607. return TRUE;
  608. }
  609. static int schema_any(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr extType, sdlTypePtr cur_type)
  610. {
  611. return TRUE;
  612. }
  613. /*
  614. <complexContent
  615. id = ID
  616. mixed = boolean
  617. {any attributes with non-schema namespace . . .}>
  618. Content: (annotation?, (restriction | extension))
  619. </complexContent>
  620. */
  621. static int schema_complexContent(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compCont, sdlTypePtr cur_type)
  622. {
  623. xmlNodePtr content;
  624. content = get_node(compCont->children, "restriction");
  625. if(content != NULL) {
  626. schema_restriction_complexContent(sdl, tsn, content, cur_type);
  627. return TRUE;
  628. }
  629. content = get_node(compCont->children, "extension");
  630. if(content == NULL) {
  631. // php_error(E_ERROR, "Error parsing schema (doesn't support extensions on complexContent)");
  632. schema_extension_complexContent(sdl, tsn, content, cur_type);
  633. return TRUE;
  634. }
  635. return TRUE;
  636. }
  637. /*
  638. <complexType
  639. abstract = boolean : false
  640. block = (#all | List of (extension | restriction))
  641. final = (#all | List of (extension | restriction))
  642. id = ID
  643. mixed = boolean : false
  644. name = NCName
  645. {any attributes with non-schema namespace . . .}>
  646. Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?))))
  647. </complexType>
  648. */
  649. static int schema_complexType(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr compType, sdlTypePtr cur_type)
  650. {
  651. xmlNodePtr content;
  652. xmlAttrPtr attrs, name, ns;
  653. attrs = compType->properties;
  654. ns = get_attribute(attrs, "targetNamespace");
  655. if(ns == NULL) {
  656. ns = tsn;
  657. }
  658. name = get_attribute(attrs, "name");
  659. if(name) {
  660. HashTable *ht;
  661. sdlTypePtr newType, *ptr;
  662. smart_str key = {0};
  663. newType = malloc(sizeof(sdlType));
  664. memset(newType, 0, sizeof(sdlType));
  665. newType->name = strdup(name->children->content);
  666. newType->namens = strdup(ns->children->content);
  667. if(cur_type == NULL) {
  668. ht = (*sdl)->types;
  669. smart_str_appends(&key, newType->namens);
  670. smart_str_appendc(&key, ':');
  671. smart_str_appends(&key, newType->name);
  672. smart_str_0(&key);
  673. } else {
  674. if(cur_type->elements == NULL) {
  675. cur_type->elements = malloc(sizeof(HashTable));
  676. zend_hash_init(cur_type->elements, 0, NULL, delete_type, 1);
  677. }
  678. ht = cur_type->elements;
  679. smart_str_appends(&key, newType->name);
  680. }
  681. zend_hash_add(ht, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&ptr);
  682. cur_type = (*ptr);
  683. create_encoder((*sdl), cur_type, ns->children->content, name->children->content);
  684. smart_str_free(&key);
  685. }
  686. content = get_node(compType->children, "simpleContent");
  687. if(content != NULL) {
  688. schema_simpleContent(sdl, tsn, content, cur_type);
  689. return TRUE;
  690. }
  691. content = get_node(compType->children, "complexContent");
  692. if(content != NULL) {
  693. schema_complexContent(sdl, tsn, content, cur_type);
  694. return TRUE;
  695. }
  696. /* (group | all | choice | sequence) */
  697. content = get_node(compType->children, "group");
  698. if(content != NULL) {
  699. schema_group(sdl, tsn, content, cur_type);
  700. return TRUE;
  701. }
  702. content = get_node(compType->children, "all");
  703. if(content != NULL) {
  704. schema_all(sdl, tsn, content, cur_type);
  705. return TRUE;
  706. }
  707. content = get_node(compType->children, "choice");
  708. if(content != NULL) {
  709. schema_choice(sdl, tsn, content, cur_type);
  710. return TRUE;
  711. }
  712. content = get_node(compType->children, "sequence");
  713. if(content != NULL) {
  714. schema_sequence(sdl, tsn, content, cur_type);
  715. }
  716. // if (cur_type->encode == NULL) {
  717. // cur_type->encode = get_conversion(SOAP_ENC_OBJECT);
  718. // }
  719. return TRUE;
  720. }
  721. /*
  722. <element
  723. abstract = boolean : false
  724. block = (#all | List of (extension | restriction | substitution))
  725. default = string
  726. final = (#all | List of (extension | restriction))
  727. fixed = string
  728. form = (qualified | unqualified)
  729. id = ID
  730. maxOccurs = (nonNegativeInteger | unbounded) : 1
  731. minOccurs = nonNegativeInteger : 1
  732. name = NCName
  733. nillable = boolean : false
  734. ref = QName
  735. substitutionGroup = QName
  736. type = QName
  737. {any attributes with non-schema namespace . . .}>
  738. Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
  739. </element>
  740. */
  741. static int schema_element(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr element, sdlTypePtr cur_type)
  742. {
  743. xmlNodePtr content;
  744. xmlAttrPtr attrs, curattr, name, ns;
  745. TSRMLS_FETCH(); /* is this really needed - or the parameter */
  746. attrs = element->properties;
  747. ns = get_attribute(attrs, "targetNamespace");
  748. if(ns == NULL) {
  749. ns = tsn;
  750. }
  751. name = get_attribute(attrs, "name");
  752. if (!name) {
  753. name = get_attribute(attrs, "ref");
  754. }
  755. if(name) {
  756. HashTable *addHash;
  757. sdlTypePtr newType, *tmp;
  758. smart_str key = {0};
  759. newType = malloc(sizeof(sdlType));
  760. memset(newType, 0, sizeof(sdlType));
  761. newType->name = strdup(name->children->content);
  762. newType->namens = strdup(tsn->children->content);
  763. newType->nillable = FALSE;
  764. newType->min_occurs = 1;
  765. newType->max_occurs = 1;
  766. if(cur_type == NULL) {
  767. addHash = (*sdl)->types;
  768. smart_str_appends(&key, newType->namens);
  769. smart_str_appendc(&key, ':');
  770. smart_str_appends(&key, newType->name);
  771. } else {
  772. if(cur_type->elements == NULL) {
  773. cur_type->elements = malloc(sizeof(HashTable));
  774. zend_hash_init(cur_type->elements, 0, NULL, delete_type, 1);
  775. }
  776. addHash = cur_type->elements;
  777. smart_str_appends(&key, newType->name);
  778. }
  779. smart_str_0(&key);
  780. zend_hash_add(addHash, key.c, key.len + 1, &newType, sizeof(sdlTypePtr), (void **)&tmp);
  781. cur_type = (*tmp);
  782. // create_encoder((*sdl), cur_type, ns->children->content, name->children->content);
  783. smart_str_free(&key);
  784. }
  785. curattr = get_attribute(attrs, "maxOccurs");
  786. if(curattr) {
  787. if(!strcmp(curattr->children->content, "unbounded")) {
  788. cur_type->max_occurs = -1;
  789. } else {
  790. cur_type->max_occurs = atoi(curattr->children->content);
  791. }
  792. }
  793. curattr = get_attribute(attrs, "minOccurs");
  794. if(curattr) {
  795. cur_type->min_occurs = atoi(curattr->children->content);
  796. }
  797. /* nillable = boolean : false */
  798. attrs = element->properties;
  799. curattr = get_attribute(attrs, "nillable");
  800. if(curattr) {
  801. if(!stricmp(curattr->children->content, "true") ||
  802. !stricmp(curattr->children->content, "1")) {
  803. cur_type->nillable = TRUE;
  804. } else {
  805. cur_type->nillable = FALSE;
  806. }
  807. } else {
  808. cur_type->nillable = FALSE;
  809. }
  810. /* type = QName */
  811. curattr = get_attribute(attrs, "type");
  812. if(!curattr) {
  813. curattr = name;
  814. }
  815. if(curattr) {
  816. char *cptype, *str_ns;
  817. xmlNsPtr nsptr;
  818. parse_namespace(curattr->children->content, &cptype, &str_ns);
  819. // if(str_ns)
  820. nsptr = xmlSearchNs(element->doc, element, str_ns);
  821. // else
  822. // nsptr = xmlSearchNsByHref(element->doc, element, ns->children->content);
  823. cur_type->encode = get_create_encoder((*sdl), cur_type, (char *)nsptr->href, (char *)cptype);
  824. if(str_ns) {efree(str_ns);}
  825. if(cptype) {efree(cptype);}
  826. }
  827. // if(cur_type->max_occurs == -1 || cur_type->max_occurs > 1)
  828. // cur_type->encode = get_conversion(SOAP_ENC_ARRAY);
  829. content = get_node(element->children, "simpleType");
  830. if(content) {
  831. schema_simpleType(sdl, tsn, content, cur_type);
  832. }
  833. content = get_node(element->children, "complexType");
  834. if(content) {
  835. schema_complexType(sdl, tsn, content, cur_type);
  836. }
  837. return FALSE;
  838. }
  839. /*
  840. <attribute
  841. default = string
  842. fixed = string
  843. form = (qualified | unqualified)
  844. id = ID
  845. name = NCName
  846. ref = QName
  847. type = QName
  848. use = (optional | prohibited | required) : optional
  849. {any attributes with non-schema namespace . . .}>
  850. Content: (annotation?, (simpleType?))
  851. </attribute>
  852. */
  853. static int schema_attribute(sdlPtr *sdl, xmlAttrPtr tsn, xmlNodePtr attrType, sdlTypePtr cur_type)
  854. {
  855. xmlAttrPtr attr;
  856. sdlAttributePtr newAttr;
  857. xmlAttrPtr trav;
  858. smart_str key = {0};
  859. newAttr = malloc(sizeof(sdlAttribute));
  860. memset(newAttr, 0, sizeof(sdlAttribute));
  861. if(cur_type->attributes == NULL) {
  862. cur_type->attributes = malloc(sizeof(HashTable));
  863. zend_hash_init(cur_type->attributes, 0, NULL, delete_attribute, 1);
  864. }
  865. trav = attrType->properties;
  866. FOREACHATTRNODE(trav, NULL, attr) {
  867. if(attr_is_equal_ex(trav, "default", SCHEMA_NAMESPACE)) {
  868. newAttr->def = strdup(attr->children->content);
  869. } else if(attr_is_equal_ex(trav, "fixed", SCHEMA_NAMESPACE)) {
  870. newAttr->fixed = strdup(attr->children->content);
  871. } else if(attr_is_equal_ex(trav, "form", SCHEMA_NAMESPACE)) {
  872. newAttr->form = strdup(attr->children->content);
  873. } else if(attr_is_equal_ex(trav, "id", SCHEMA_NAMESPACE)) {
  874. newAttr->id = strdup(attr->children->content);
  875. } else if(attr_is_equal_ex(trav, "name", SCHEMA_NAMESPACE)) {
  876. newAttr->name = strdup(attr->children->content);
  877. } else if(attr_is_equal_ex(trav, "ref", SCHEMA_NAMESPACE)) {
  878. newAttr->ref= strdup(attr->children->content);
  879. } else if(attr_is_equal_ex(trav, "type", SCHEMA_NAMESPACE)) {
  880. newAttr->type = strdup(attr->children->content);
  881. } else if(attr_is_equal_ex(trav, "use", SCHEMA_NAMESPACE)) {
  882. newAttr->use = strdup(attr->children->content);
  883. } else {
  884. xmlNsPtr nsPtr = attr_find_ns(trav);
  885. if(strcmp(nsPtr->href, SCHEMA_NAMESPACE)) {
  886. smart_str key2 = {0};
  887. if(!newAttr->extraAttributes) {
  888. newAttr->extraAttributes = malloc(sizeof(HashTable));
  889. zend_hash_init(newAttr->extraAttributes, 0, NULL, NULL, 1);
  890. }
  891. smart_str_appends(&key2, nsPtr->href);
  892. smart_str_appendc(&key2, ':');
  893. smart_str_appends(&key2, trav->name);
  894. smart_str_0(&key2);
  895. zend_hash_add(newAttr->extraAttributes, key2.c, key2.len + 1, &trav, sizeof(xmlAttrPtr), NULL);
  896. smart_str_free(&key2);
  897. }
  898. }
  899. }
  900. ENDFOREACH(trav);
  901. if(newAttr->ref || newAttr->name) {
  902. xmlNsPtr ns;
  903. if(newAttr->ref) {
  904. char *value, *prefix = NULL;
  905. parse_namespace(newAttr->ref, &value, &prefix);
  906. ns = xmlSearchNs(attrType->doc, attrType, prefix);
  907. smart_str_appends(&key, ns->href);
  908. smart_str_appendc(&key, ':');
  909. smart_str_appends(&key, value);
  910. if(value) {efree(value);}
  911. if(prefix) {efree(prefix);}
  912. } else {
  913. ns = node_find_ns(attrType);
  914. smart_str_appends(&key, ns->href);
  915. smart_str_appendc(&key, ':');
  916. smart_str_appends(&key, newAttr->name);
  917. }
  918. if(ns) {
  919. smart_str_0(&key);
  920. zend_hash_add(cur_type->attributes, key.c, key.len + 1, &newAttr, sizeof(sdlAttributePtr), NULL);
  921. smart_str_free(&key);
  922. return TRUE;
  923. }
  924. }
  925. zend_hash_next_index_insert(cur_type->attributes, &newAttr, sizeof(sdlAttributePtr), NULL);
  926. return TRUE;
  927. }