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.

1075 lines
27 KiB

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