element.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Christian Stocker <chregu@php.net> |
  16. | Rob Richards <rrichards@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id$ */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "php.h"
  24. #if HAVE_LIBXML && HAVE_DOM
  25. #include "php_dom.h"
  26. /* {{{ arginfo */
  27. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute, 0, 0, 1)
  28. ZEND_ARG_INFO(0, name)
  29. ZEND_END_ARG_INFO();
  30. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute, 0, 0, 2)
  31. ZEND_ARG_INFO(0, name)
  32. ZEND_ARG_INFO(0, value)
  33. ZEND_END_ARG_INFO();
  34. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute, 0, 0, 1)
  35. ZEND_ARG_INFO(0, name)
  36. ZEND_END_ARG_INFO();
  37. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node, 0, 0, 1)
  38. ZEND_ARG_INFO(0, name)
  39. ZEND_END_ARG_INFO();
  40. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node, 0, 0, 1)
  41. ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0)
  42. ZEND_END_ARG_INFO();
  43. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_node, 0, 0, 1)
  44. ZEND_ARG_OBJ_INFO(0, oldAttr, DOMAttr, 0)
  45. ZEND_END_ARG_INFO();
  46. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name, 0, 0, 1)
  47. ZEND_ARG_INFO(0, name)
  48. ZEND_END_ARG_INFO();
  49. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_ns, 0, 0, 2)
  50. ZEND_ARG_INFO(0, namespaceURI)
  51. ZEND_ARG_INFO(0, localName)
  52. ZEND_END_ARG_INFO();
  53. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_ns, 0, 0, 3)
  54. ZEND_ARG_INFO(0, namespaceURI)
  55. ZEND_ARG_INFO(0, qualifiedName)
  56. ZEND_ARG_INFO(0, value)
  57. ZEND_END_ARG_INFO();
  58. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_ns, 0, 0, 2)
  59. ZEND_ARG_INFO(0, namespaceURI)
  60. ZEND_ARG_INFO(0, localName)
  61. ZEND_END_ARG_INFO();
  62. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node_ns, 0, 0, 2)
  63. ZEND_ARG_INFO(0, namespaceURI)
  64. ZEND_ARG_INFO(0, localName)
  65. ZEND_END_ARG_INFO();
  66. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node_ns, 0, 0, 1)
  67. ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0)
  68. ZEND_END_ARG_INFO();
  69. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name_ns, 0, 0, 2)
  70. ZEND_ARG_INFO(0, namespaceURI)
  71. ZEND_ARG_INFO(0, localName)
  72. ZEND_END_ARG_INFO();
  73. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute, 0, 0, 1)
  74. ZEND_ARG_INFO(0, name)
  75. ZEND_END_ARG_INFO();
  76. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute_ns, 0, 0, 2)
  77. ZEND_ARG_INFO(0, namespaceURI)
  78. ZEND_ARG_INFO(0, localName)
  79. ZEND_END_ARG_INFO();
  80. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute, 0, 0, 2)
  81. ZEND_ARG_INFO(0, name)
  82. ZEND_ARG_INFO(0, isId)
  83. ZEND_END_ARG_INFO();
  84. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_ns, 0, 0, 3)
  85. ZEND_ARG_INFO(0, namespaceURI)
  86. ZEND_ARG_INFO(0, localName)
  87. ZEND_ARG_INFO(0, isId)
  88. ZEND_END_ARG_INFO();
  89. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_node, 0, 0, 2)
  90. ZEND_ARG_OBJ_INFO(0, attr, DOMAttr, 0)
  91. ZEND_ARG_INFO(0, isId)
  92. ZEND_END_ARG_INFO();
  93. ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_construct, 0, 0, 1)
  94. ZEND_ARG_INFO(0, name)
  95. ZEND_ARG_INFO(0, value)
  96. ZEND_ARG_INFO(0, uri)
  97. ZEND_END_ARG_INFO();
  98. /* }}} */
  99. /*
  100. * class DOMElement extends DOMNode
  101. *
  102. * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-745549614
  103. * Since:
  104. */
  105. const zend_function_entry php_dom_element_class_functions[] = { /* {{{ */
  106. PHP_FALIAS(getAttribute, dom_element_get_attribute, arginfo_dom_element_get_attribute)
  107. PHP_FALIAS(setAttribute, dom_element_set_attribute, arginfo_dom_element_set_attribute)
  108. PHP_FALIAS(removeAttribute, dom_element_remove_attribute, arginfo_dom_element_remove_attribute)
  109. PHP_FALIAS(getAttributeNode, dom_element_get_attribute_node, arginfo_dom_element_get_attribute_node)
  110. PHP_FALIAS(setAttributeNode, dom_element_set_attribute_node, arginfo_dom_element_set_attribute_node)
  111. PHP_FALIAS(removeAttributeNode, dom_element_remove_attribute_node, arginfo_dom_element_remove_attribute_node)
  112. PHP_FALIAS(getElementsByTagName, dom_element_get_elements_by_tag_name, arginfo_dom_element_get_elements_by_tag_name)
  113. PHP_FALIAS(getAttributeNS, dom_element_get_attribute_ns, arginfo_dom_element_get_attribute_ns)
  114. PHP_FALIAS(setAttributeNS, dom_element_set_attribute_ns, arginfo_dom_element_set_attribute_ns)
  115. PHP_FALIAS(removeAttributeNS, dom_element_remove_attribute_ns, arginfo_dom_element_remove_attribute_ns)
  116. PHP_FALIAS(getAttributeNodeNS, dom_element_get_attribute_node_ns, arginfo_dom_element_get_attribute_node_ns)
  117. PHP_FALIAS(setAttributeNodeNS, dom_element_set_attribute_node_ns, arginfo_dom_element_set_attribute_node_ns)
  118. PHP_FALIAS(getElementsByTagNameNS, dom_element_get_elements_by_tag_name_ns, arginfo_dom_element_get_elements_by_tag_name_ns)
  119. PHP_FALIAS(hasAttribute, dom_element_has_attribute, arginfo_dom_element_has_attribute)
  120. PHP_FALIAS(hasAttributeNS, dom_element_has_attribute_ns, arginfo_dom_element_has_attribute_ns)
  121. PHP_FALIAS(setIdAttribute, dom_element_set_id_attribute, arginfo_dom_element_set_id_attribute)
  122. PHP_FALIAS(setIdAttributeNS, dom_element_set_id_attribute_ns, arginfo_dom_element_set_id_attribute_ns)
  123. PHP_FALIAS(setIdAttributeNode, dom_element_set_id_attribute_node, arginfo_dom_element_set_id_attribute_node)
  124. PHP_ME(domelement, __construct, arginfo_dom_element_construct, ZEND_ACC_PUBLIC)
  125. PHP_FE_END
  126. };
  127. /* }}} */
  128. /* {{{ proto void DOMElement::__construct(string name, [string value], [string uri]); */
  129. PHP_METHOD(domelement, __construct)
  130. {
  131. zval *id;
  132. xmlNodePtr nodep = NULL, oldnode = NULL;
  133. dom_object *intern;
  134. char *name, *value = NULL, *uri = NULL;
  135. char *localname = NULL, *prefix = NULL;
  136. int errorcode = 0, uri_len = 0;
  137. int name_len, value_len = 0, name_valid;
  138. xmlNsPtr nsptr = NULL;
  139. zend_error_handling error_handling;
  140. zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
  141. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s!s", &id, dom_element_class_entry, &name, &name_len, &value, &value_len, &uri, &uri_len) == FAILURE) {
  142. zend_restore_error_handling(&error_handling TSRMLS_CC);
  143. return;
  144. }
  145. zend_restore_error_handling(&error_handling TSRMLS_CC);
  146. name_valid = xmlValidateName((xmlChar *) name, 0);
  147. if (name_valid != 0) {
  148. php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
  149. RETURN_FALSE;
  150. }
  151. /* Namespace logic is separate and only when uri passed in to insure no BC breakage */
  152. if (uri_len > 0) {
  153. errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
  154. if (errorcode == 0) {
  155. nodep = xmlNewNode (NULL, (xmlChar *)localname);
  156. if (nodep != NULL && uri != NULL) {
  157. nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
  158. xmlSetNs(nodep, nsptr);
  159. }
  160. }
  161. xmlFree(localname);
  162. if (prefix != NULL) {
  163. xmlFree(prefix);
  164. }
  165. if (errorcode != 0) {
  166. if (nodep != NULL) {
  167. xmlFreeNode(nodep);
  168. }
  169. php_dom_throw_error(errorcode, 1 TSRMLS_CC);
  170. RETURN_FALSE;
  171. }
  172. } else {
  173. /* If you don't pass a namespace uri, then you can't set a prefix */
  174. localname = xmlSplitQName2((xmlChar *)name, (xmlChar **) &prefix);
  175. if (prefix != NULL) {
  176. xmlFree(localname);
  177. xmlFree(prefix);
  178. php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC);
  179. RETURN_FALSE;
  180. }
  181. nodep = xmlNewNode(NULL, (xmlChar *) name);
  182. }
  183. if (!nodep) {
  184. php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
  185. RETURN_FALSE;
  186. }
  187. if (value_len > 0) {
  188. xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len);
  189. }
  190. intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
  191. if (intern != NULL) {
  192. oldnode = dom_object_get_node(intern);
  193. if (oldnode != NULL) {
  194. php_libxml_node_free_resource(oldnode TSRMLS_CC);
  195. }
  196. php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
  197. }
  198. }
  199. /* }}} end DOMElement::__construct */
  200. /* {{{ tagName string
  201. readonly=yes
  202. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-104682815
  203. Since:
  204. */
  205. int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC)
  206. {
  207. xmlNodePtr nodep;
  208. xmlNsPtr ns;
  209. xmlChar *qname;
  210. nodep = dom_object_get_node(obj);
  211. if (nodep == NULL) {
  212. php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
  213. return FAILURE;
  214. }
  215. ALLOC_ZVAL(*retval);
  216. ns = nodep->ns;
  217. if (ns != NULL && ns->prefix) {
  218. qname = xmlStrdup(ns->prefix);
  219. qname = xmlStrcat(qname, (xmlChar *)":");
  220. qname = xmlStrcat(qname, nodep->name);
  221. ZVAL_STRING(*retval, (char *)qname, 1);
  222. xmlFree(qname);
  223. } else {
  224. ZVAL_STRING(*retval, (char *) nodep->name, 1);
  225. }
  226. return SUCCESS;
  227. }
  228. /* }}} */
  229. /* {{{ schemaTypeInfo typeinfo
  230. readonly=yes
  231. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Element-schemaTypeInfo
  232. Since: DOM Level 3
  233. */
  234. int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC)
  235. {
  236. ALLOC_ZVAL(*retval);
  237. ZVAL_NULL(*retval);
  238. return SUCCESS;
  239. }
  240. /* }}} */
  241. static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) /* {{{ */
  242. {
  243. int len;
  244. const xmlChar *nqname;
  245. nqname = xmlSplitQName3(name, &len);
  246. if (nqname != NULL) {
  247. xmlNsPtr ns;
  248. xmlChar *prefix = xmlStrndup(name, len);
  249. if (prefix && xmlStrEqual(prefix, (xmlChar *)"xmlns")) {
  250. ns = elem->nsDef;
  251. while (ns) {
  252. if (xmlStrEqual(ns->prefix, nqname)) {
  253. break;
  254. }
  255. ns = ns->next;
  256. }
  257. xmlFree(prefix);
  258. return (xmlNodePtr)ns;
  259. }
  260. ns = xmlSearchNs(elem->doc, elem, prefix);
  261. if (prefix != NULL) {
  262. xmlFree(prefix);
  263. }
  264. if (ns != NULL) {
  265. return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
  266. }
  267. } else {
  268. if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
  269. xmlNsPtr nsPtr = elem->nsDef;
  270. while (nsPtr) {
  271. if (nsPtr->prefix == NULL) {
  272. return (xmlNodePtr)nsPtr;
  273. }
  274. nsPtr = nsPtr->next;
  275. }
  276. return NULL;
  277. }
  278. }
  279. return (xmlNodePtr)xmlHasNsProp(elem, name, NULL);
  280. }
  281. /* }}} */
  282. /* {{{ proto string dom_element_get_attribute(string name);
  283. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9
  284. Since:
  285. */
  286. PHP_FUNCTION(dom_element_get_attribute)
  287. {
  288. zval *id;
  289. xmlNode *nodep;
  290. char *name;
  291. xmlChar *value = NULL;
  292. dom_object *intern;
  293. xmlNodePtr attr;
  294. int name_len;
  295. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
  296. return;
  297. }
  298. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  299. attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
  300. if (attr) {
  301. switch (attr->type) {
  302. case XML_ATTRIBUTE_NODE:
  303. value = xmlNodeListGetString(attr->doc, attr->children, 1);
  304. break;
  305. case XML_NAMESPACE_DECL:
  306. value = xmlStrdup(((xmlNsPtr)attr)->href);
  307. break;
  308. default:
  309. value = xmlStrdup(((xmlAttributePtr)attr)->defaultValue);
  310. }
  311. }
  312. if (value == NULL) {
  313. RETURN_EMPTY_STRING();
  314. } else {
  315. RETVAL_STRING((char *)value, 1);
  316. xmlFree(value);
  317. }
  318. }
  319. /* }}} end dom_element_get_attribute */
  320. /* {{{ proto void dom_element_set_attribute(string name, string value);
  321. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082
  322. Since:
  323. */
  324. PHP_FUNCTION(dom_element_set_attribute)
  325. {
  326. zval *id;
  327. xmlNode *nodep;
  328. xmlNodePtr attr = NULL;
  329. int ret, name_len, value_len, name_valid;
  330. dom_object *intern;
  331. char *name, *value;
  332. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
  333. return;
  334. }
  335. if (name_len == 0) {
  336. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
  337. RETURN_FALSE;
  338. }
  339. name_valid = xmlValidateName((xmlChar *) name, 0);
  340. if (name_valid != 0) {
  341. php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
  342. RETURN_FALSE;
  343. }
  344. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  345. if (dom_node_is_read_only(nodep) == SUCCESS) {
  346. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  347. RETURN_FALSE;
  348. }
  349. attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
  350. if (attr != NULL) {
  351. switch (attr->type) {
  352. case XML_ATTRIBUTE_NODE:
  353. node_list_unlink(attr->children TSRMLS_CC);
  354. break;
  355. case XML_NAMESPACE_DECL:
  356. RETURN_FALSE;
  357. default:
  358. break;
  359. }
  360. }
  361. if (xmlStrEqual((xmlChar *)name, (xmlChar *)"xmlns")) {
  362. if (xmlNewNs(nodep, (xmlChar *)value, NULL)) {
  363. RETURN_TRUE;
  364. }
  365. } else {
  366. attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, (xmlChar *)value);
  367. }
  368. if (!attr) {
  369. php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name);
  370. RETURN_FALSE;
  371. }
  372. DOM_RET_OBJ(attr, &ret, intern);
  373. }
  374. /* }}} end dom_element_set_attribute */
  375. /* {{{ proto void dom_element_remove_attribute(string name);
  376. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9
  377. Since:
  378. */
  379. PHP_FUNCTION(dom_element_remove_attribute)
  380. {
  381. zval *id;
  382. xmlNodePtr nodep, attrp;
  383. dom_object *intern;
  384. int name_len;
  385. char *name;
  386. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
  387. return;
  388. }
  389. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  390. if (dom_node_is_read_only(nodep) == SUCCESS) {
  391. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  392. RETURN_FALSE;
  393. }
  394. attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
  395. if (attrp == NULL) {
  396. RETURN_FALSE;
  397. }
  398. switch (attrp->type) {
  399. case XML_ATTRIBUTE_NODE:
  400. if (php_dom_object_get_data(attrp) == NULL) {
  401. node_list_unlink(attrp->children TSRMLS_CC);
  402. xmlUnlinkNode(attrp);
  403. xmlFreeProp((xmlAttrPtr)attrp);
  404. } else {
  405. xmlUnlinkNode(attrp);
  406. }
  407. break;
  408. case XML_NAMESPACE_DECL:
  409. RETURN_FALSE;
  410. default:
  411. break;
  412. }
  413. RETURN_TRUE;
  414. }
  415. /* }}} end dom_element_remove_attribute */
  416. /* {{{ proto DOMAttr dom_element_get_attribute_node(string name);
  417. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8
  418. Since:
  419. */
  420. PHP_FUNCTION(dom_element_get_attribute_node)
  421. {
  422. zval *id;
  423. xmlNodePtr nodep, attrp;
  424. int name_len, ret;
  425. dom_object *intern;
  426. char *name;
  427. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
  428. return;
  429. }
  430. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  431. attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
  432. if (attrp == NULL) {
  433. RETURN_FALSE;
  434. }
  435. if (attrp->type == XML_NAMESPACE_DECL) {
  436. xmlNsPtr curns;
  437. xmlNodePtr nsparent;
  438. nsparent = attrp->_private;
  439. curns = xmlNewNs(NULL, attrp->name, NULL);
  440. if (attrp->children) {
  441. curns->prefix = xmlStrdup((xmlChar *) attrp->children);
  442. }
  443. if (attrp->children) {
  444. attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *) attrp->children, attrp->name);
  445. } else {
  446. attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *)"xmlns", attrp->name);
  447. }
  448. attrp->type = XML_NAMESPACE_DECL;
  449. attrp->parent = nsparent;
  450. attrp->ns = curns;
  451. }
  452. DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
  453. }
  454. /* }}} end dom_element_get_attribute_node */
  455. /* {{{ proto DOMAttr dom_element_set_attribute_node(DOMAttr newAttr);
  456. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154
  457. Since:
  458. */
  459. PHP_FUNCTION(dom_element_set_attribute_node)
  460. {
  461. zval *id, *node;
  462. xmlNode *nodep;
  463. xmlAttr *attrp, *existattrp = NULL;
  464. dom_object *intern, *attrobj, *oldobj;
  465. int ret;
  466. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
  467. return;
  468. }
  469. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  470. if (dom_node_is_read_only(nodep) == SUCCESS) {
  471. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  472. RETURN_FALSE;
  473. }
  474. DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
  475. if (attrp->type != XML_ATTRIBUTE_NODE) {
  476. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required");
  477. RETURN_FALSE;
  478. }
  479. if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
  480. php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  481. RETURN_FALSE;
  482. }
  483. existattrp = xmlHasProp(nodep, attrp->name);
  484. if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
  485. if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
  486. ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
  487. {
  488. RETURN_NULL();
  489. }
  490. xmlUnlinkNode((xmlNodePtr) existattrp);
  491. }
  492. if (attrp->parent != NULL) {
  493. xmlUnlinkNode((xmlNodePtr) attrp);
  494. }
  495. if (attrp->doc == NULL && nodep->doc != NULL) {
  496. attrobj->document = intern->document;
  497. php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
  498. }
  499. xmlAddChild(nodep, (xmlNodePtr) attrp);
  500. /* Returns old property if removed otherwise NULL */
  501. if (existattrp != NULL) {
  502. DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern);
  503. } else {
  504. RETVAL_NULL();
  505. }
  506. }
  507. /* }}} end dom_element_set_attribute_node */
  508. /* {{{ proto DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr);
  509. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198
  510. Since:
  511. */
  512. PHP_FUNCTION(dom_element_remove_attribute_node)
  513. {
  514. zval *id, *node;
  515. xmlNode *nodep;
  516. xmlAttr *attrp;
  517. dom_object *intern, *attrobj;
  518. int ret;
  519. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
  520. return;
  521. }
  522. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  523. if (dom_node_is_read_only(nodep) == SUCCESS) {
  524. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  525. RETURN_FALSE;
  526. }
  527. DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
  528. if (attrp->type != XML_ATTRIBUTE_NODE || attrp->parent != nodep) {
  529. php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  530. RETURN_FALSE;
  531. }
  532. xmlUnlinkNode((xmlNodePtr) attrp);
  533. DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
  534. }
  535. /* }}} end dom_element_remove_attribute_node */
  536. /* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name(string name);
  537. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D
  538. Since:
  539. */
  540. PHP_FUNCTION(dom_element_get_elements_by_tag_name)
  541. {
  542. zval *id;
  543. xmlNodePtr elemp;
  544. int name_len;
  545. dom_object *intern, *namednode;
  546. char *name;
  547. xmlChar *local;
  548. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
  549. return;
  550. }
  551. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  552. php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
  553. namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
  554. local = xmlCharStrndup(name, name_len);
  555. dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
  556. }
  557. /* }}} end dom_element_get_elements_by_tag_name */
  558. /* {{{ proto string dom_element_get_attribute_ns(string namespaceURI, string localName);
  559. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS
  560. Since: DOM Level 2
  561. */
  562. PHP_FUNCTION(dom_element_get_attribute_ns)
  563. {
  564. zval *id;
  565. xmlNodePtr elemp;
  566. xmlNsPtr nsptr;
  567. dom_object *intern;
  568. int uri_len = 0, name_len = 0;
  569. char *uri, *name;
  570. xmlChar *strattr;
  571. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  572. return;
  573. }
  574. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  575. strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri);
  576. if (strattr != NULL) {
  577. RETVAL_STRING((char *)strattr, 1);
  578. xmlFree(strattr);
  579. } else {
  580. if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
  581. nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
  582. if (nsptr != NULL) {
  583. RETVAL_STRING((char *) nsptr->href, 1);
  584. } else {
  585. RETVAL_EMPTY_STRING();
  586. }
  587. } else {
  588. RETVAL_EMPTY_STRING();
  589. }
  590. }
  591. }
  592. /* }}} end dom_element_get_attribute_ns */
  593. static xmlNsPtr _dom_new_reconNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) /* {{{ */
  594. {
  595. xmlNsPtr def;
  596. xmlChar prefix[50];
  597. int counter = 1;
  598. if ((tree == NULL) || (ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
  599. return NULL;
  600. }
  601. /* Code taken from libxml2 (2.6.20) xmlNewReconciliedNs
  602. *
  603. * Find a close prefix which is not already in use.
  604. * Let's strip namespace prefixes longer than 20 chars !
  605. */
  606. if (ns->prefix == NULL)
  607. snprintf((char *) prefix, sizeof(prefix), "default");
  608. else
  609. snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix);
  610. def = xmlSearchNs(doc, tree, prefix);
  611. while (def != NULL) {
  612. if (counter > 1000) return(NULL);
  613. if (ns->prefix == NULL)
  614. snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
  615. else
  616. snprintf((char *) prefix, sizeof(prefix), "%.20s%d",
  617. (char *)ns->prefix, counter++);
  618. def = xmlSearchNs(doc, tree, prefix);
  619. }
  620. /*
  621. * OK, now we are ready to create a new one.
  622. */
  623. def = xmlNewNs(tree, ns->href, prefix);
  624. return(def);
  625. }
  626. /* }}} */
  627. /* {{{ proto void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value);
  628. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS
  629. Since: DOM Level 2
  630. */
  631. PHP_FUNCTION(dom_element_set_attribute_ns)
  632. {
  633. zval *id;
  634. xmlNodePtr elemp, nodep = NULL;
  635. xmlNsPtr nsptr;
  636. xmlAttr *attr;
  637. int uri_len = 0, name_len = 0, value_len = 0;
  638. char *uri, *name, *value;
  639. char *localname = NULL, *prefix = NULL;
  640. dom_object *intern;
  641. int errorcode = 0, stricterror, is_xmlns = 0, name_valid;
  642. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!ss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
  643. return;
  644. }
  645. if (name_len == 0) {
  646. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
  647. RETURN_FALSE;
  648. }
  649. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  650. stricterror = dom_get_strict_error(intern->document);
  651. if (dom_node_is_read_only(elemp) == SUCCESS) {
  652. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
  653. RETURN_NULL();
  654. }
  655. errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
  656. if (errorcode == 0) {
  657. if (uri_len > 0) {
  658. nodep = (xmlNodePtr) xmlHasNsProp(elemp, (xmlChar *) localname, (xmlChar *) uri);
  659. if (nodep != NULL && nodep->type != XML_ATTRIBUTE_DECL) {
  660. node_list_unlink(nodep->children TSRMLS_CC);
  661. }
  662. if ((xmlStrEqual((xmlChar *) prefix, (xmlChar *)"xmlns") ||
  663. (prefix == NULL && xmlStrEqual((xmlChar *) localname, (xmlChar *)"xmlns"))) &&
  664. xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
  665. is_xmlns = 1;
  666. if (prefix == NULL) {
  667. nsptr = dom_get_nsdecl(elemp, NULL);
  668. } else {
  669. nsptr = dom_get_nsdecl(elemp, (xmlChar *)localname);
  670. }
  671. } else {
  672. nsptr = xmlSearchNsByHref(elemp->doc, elemp, (xmlChar *)uri);
  673. if (nsptr && nsptr->prefix == NULL) {
  674. xmlNsPtr tmpnsptr;
  675. tmpnsptr = nsptr->next;
  676. while (tmpnsptr) {
  677. if ((tmpnsptr->prefix != NULL) && (tmpnsptr->href != NULL) &&
  678. (xmlStrEqual(tmpnsptr->href, (xmlChar *) uri))) {
  679. nsptr = tmpnsptr;
  680. break;
  681. }
  682. tmpnsptr = tmpnsptr->next;
  683. }
  684. if (tmpnsptr == NULL) {
  685. nsptr = _dom_new_reconNs(elemp->doc, elemp, nsptr);
  686. }
  687. }
  688. }
  689. if (nsptr == NULL) {
  690. if (prefix == NULL) {
  691. if (is_xmlns == 1) {
  692. xmlNewNs(elemp, (xmlChar *)value, NULL);
  693. xmlReconciliateNs(elemp->doc, elemp);
  694. } else {
  695. errorcode = NAMESPACE_ERR;
  696. }
  697. } else {
  698. if (is_xmlns == 1) {
  699. xmlNewNs(elemp, (xmlChar *)value, (xmlChar *)localname);
  700. } else {
  701. nsptr = dom_get_ns(elemp, uri, &errorcode, prefix);
  702. }
  703. xmlReconciliateNs(elemp->doc, elemp);
  704. }
  705. } else {
  706. if (is_xmlns == 1) {
  707. if (nsptr->href) {
  708. xmlFree((xmlChar *) nsptr->href);
  709. }
  710. nsptr->href = xmlStrdup((xmlChar *)value);
  711. }
  712. }
  713. if (errorcode == 0 && is_xmlns == 0) {
  714. xmlSetNsProp(elemp, nsptr, (xmlChar *)localname, (xmlChar *)value);
  715. }
  716. } else {
  717. name_valid = xmlValidateName((xmlChar *) localname, 0);
  718. if (name_valid != 0) {
  719. errorcode = INVALID_CHARACTER_ERR;
  720. stricterror = 1;
  721. } else {
  722. attr = xmlHasProp(elemp, (xmlChar *)localname);
  723. if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) {
  724. node_list_unlink(attr->children TSRMLS_CC);
  725. }
  726. xmlSetProp(elemp, (xmlChar *)localname, (xmlChar *)value);
  727. }
  728. }
  729. }
  730. xmlFree(localname);
  731. if (prefix != NULL) {
  732. xmlFree(prefix);
  733. }
  734. if (errorcode != 0) {
  735. php_dom_throw_error(errorcode, stricterror TSRMLS_CC);
  736. }
  737. RETURN_NULL();
  738. }
  739. /* }}} end dom_element_set_attribute_ns */
  740. /* {{{ proto void dom_element_remove_attribute_ns(string namespaceURI, string localName);
  741. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS
  742. Since: DOM Level 2
  743. */
  744. PHP_FUNCTION(dom_element_remove_attribute_ns)
  745. {
  746. zval *id;
  747. xmlNode *nodep;
  748. xmlAttr *attrp;
  749. xmlNsPtr nsptr;
  750. dom_object *intern;
  751. int name_len, uri_len;
  752. char *name, *uri;
  753. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  754. return;
  755. }
  756. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  757. if (dom_node_is_read_only(nodep) == SUCCESS) {
  758. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  759. RETURN_NULL();
  760. }
  761. attrp = xmlHasNsProp(nodep, (xmlChar *)name, (xmlChar *)uri);
  762. nsptr = dom_get_nsdecl(nodep, (xmlChar *)name);
  763. if (nsptr != NULL) {
  764. if (xmlStrEqual((xmlChar *)uri, nsptr->href)) {
  765. if (nsptr->href != NULL) {
  766. xmlFree((char *) nsptr->href);
  767. nsptr->href = NULL;
  768. }
  769. if (nsptr->prefix != NULL) {
  770. xmlFree((char *) nsptr->prefix);
  771. nsptr->prefix = NULL;
  772. }
  773. } else {
  774. RETURN_NULL();
  775. }
  776. }
  777. if (attrp && attrp->type != XML_ATTRIBUTE_DECL) {
  778. if (php_dom_object_get_data((xmlNodePtr) attrp) == NULL) {
  779. node_list_unlink(attrp->children TSRMLS_CC);
  780. xmlUnlinkNode((xmlNodePtr) attrp);
  781. xmlFreeProp(attrp);
  782. } else {
  783. xmlUnlinkNode((xmlNodePtr) attrp);
  784. }
  785. }
  786. RETURN_NULL();
  787. }
  788. /* }}} end dom_element_remove_attribute_ns */
  789. /* {{{ proto DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName);
  790. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS
  791. Since: DOM Level 2
  792. */
  793. PHP_FUNCTION(dom_element_get_attribute_node_ns)
  794. {
  795. zval *id;
  796. xmlNodePtr elemp;
  797. xmlAttrPtr attrp;
  798. dom_object *intern;
  799. int uri_len, name_len, ret;
  800. char *uri, *name;
  801. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  802. return;
  803. }
  804. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  805. attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
  806. if (attrp == NULL) {
  807. RETURN_NULL();
  808. }
  809. DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
  810. }
  811. /* }}} end dom_element_get_attribute_node_ns */
  812. /* {{{ proto DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr);
  813. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS
  814. Since: DOM Level 2
  815. */
  816. PHP_FUNCTION(dom_element_set_attribute_node_ns)
  817. {
  818. zval *id, *node;
  819. xmlNode *nodep;
  820. xmlNs *nsp;
  821. xmlAttr *attrp, *existattrp = NULL;
  822. dom_object *intern, *attrobj, *oldobj;
  823. int ret;
  824. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
  825. return;
  826. }
  827. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  828. if (dom_node_is_read_only(nodep) == SUCCESS) {
  829. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  830. RETURN_FALSE;
  831. }
  832. DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
  833. if (attrp->type != XML_ATTRIBUTE_NODE) {
  834. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required");
  835. RETURN_FALSE;
  836. }
  837. if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
  838. php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  839. RETURN_FALSE;
  840. }
  841. nsp = attrp->ns;
  842. if (nsp != NULL) {
  843. existattrp = xmlHasNsProp(nodep, nsp->href, attrp->name);
  844. } else {
  845. existattrp = xmlHasProp(nodep, attrp->name);
  846. }
  847. if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
  848. if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
  849. ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
  850. {
  851. RETURN_NULL();
  852. }
  853. xmlUnlinkNode((xmlNodePtr) existattrp);
  854. }
  855. if (attrp->parent != NULL) {
  856. xmlUnlinkNode((xmlNodePtr) attrp);
  857. }
  858. if (attrp->doc == NULL && nodep->doc != NULL) {
  859. attrobj->document = intern->document;
  860. php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
  861. }
  862. xmlAddChild(nodep, (xmlNodePtr) attrp);
  863. /* Returns old property if removed otherwise NULL */
  864. if (existattrp != NULL) {
  865. DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern);
  866. } else {
  867. RETVAL_NULL();
  868. }
  869. }
  870. /* }}} end dom_element_set_attribute_node_ns */
  871. /* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName);
  872. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942
  873. Since: DOM Level 2
  874. */
  875. PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns)
  876. {
  877. zval *id;
  878. xmlNodePtr elemp;
  879. int uri_len, name_len;
  880. dom_object *intern, *namednode;
  881. char *uri, *name;
  882. xmlChar *local, *nsuri;
  883. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  884. return;
  885. }
  886. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  887. php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
  888. namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
  889. local = xmlCharStrndup(name, name_len);
  890. nsuri = xmlCharStrndup(uri, uri_len);
  891. dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
  892. }
  893. /* }}} end dom_element_get_elements_by_tag_name_ns */
  894. /* {{{ proto boolean dom_element_has_attribute(string name);
  895. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr
  896. Since: DOM Level 2
  897. */
  898. PHP_FUNCTION(dom_element_has_attribute)
  899. {
  900. zval *id;
  901. xmlNode *nodep;
  902. dom_object *intern;
  903. char *name;
  904. int name_len;
  905. xmlNodePtr attr;
  906. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
  907. return;
  908. }
  909. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  910. attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
  911. if (attr == NULL) {
  912. RETURN_FALSE;
  913. } else {
  914. RETURN_TRUE;
  915. }
  916. }
  917. /* }}} end dom_element_has_attribute */
  918. /* {{{ proto boolean dom_element_has_attribute_ns(string namespaceURI, string localName);
  919. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS
  920. Since: DOM Level 2
  921. */
  922. PHP_FUNCTION(dom_element_has_attribute_ns)
  923. {
  924. zval *id;
  925. xmlNodePtr elemp;
  926. xmlNs *nsp;
  927. dom_object *intern;
  928. int uri_len, name_len;
  929. char *uri, *name;
  930. xmlChar *value;
  931. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
  932. return;
  933. }
  934. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  935. value = xmlGetNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
  936. if (value != NULL) {
  937. xmlFree(value);
  938. RETURN_TRUE;
  939. } else {
  940. if (xmlStrEqual((xmlChar *)uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
  941. nsp = dom_get_nsdecl(elemp, (xmlChar *)name);
  942. if (nsp != NULL) {
  943. RETURN_TRUE;
  944. }
  945. }
  946. }
  947. RETURN_FALSE;
  948. }
  949. /* }}} end dom_element_has_attribute_ns */
  950. static void php_set_attribute_id(xmlAttrPtr attrp, zend_bool is_id) /* {{{ */
  951. {
  952. if (is_id == 1 && attrp->atype != XML_ATTRIBUTE_ID) {
  953. xmlChar *id_val;
  954. id_val = xmlNodeListGetString(attrp->doc, attrp->children, 1);
  955. if (id_val != NULL) {
  956. xmlAddID(NULL, attrp->doc, id_val, attrp);
  957. xmlFree(id_val);
  958. }
  959. } else {
  960. if (attrp->atype == XML_ATTRIBUTE_ID) {
  961. xmlRemoveID(attrp->doc, attrp);
  962. attrp->atype = 0;
  963. }
  964. }
  965. }
  966. /* }}} */
  967. /* {{{ proto void dom_element_set_id_attribute(string name, boolean isId);
  968. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr
  969. Since: DOM Level 3
  970. */
  971. PHP_FUNCTION(dom_element_set_id_attribute)
  972. {
  973. zval *id;
  974. xmlNode *nodep;
  975. xmlAttrPtr attrp;
  976. dom_object *intern;
  977. char *name;
  978. int name_len;
  979. zend_bool is_id;
  980. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osb", &id, dom_element_class_entry, &name, &name_len, &is_id) == FAILURE) {
  981. return;
  982. }
  983. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  984. if (dom_node_is_read_only(nodep) == SUCCESS) {
  985. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  986. RETURN_NULL();
  987. }
  988. attrp = xmlHasNsProp(nodep, (xmlChar *)name, NULL);
  989. if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
  990. php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  991. } else {
  992. php_set_attribute_id(attrp, is_id);
  993. }
  994. RETURN_NULL();
  995. }
  996. /* }}} end dom_element_set_id_attribute */
  997. /* {{{ proto void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId);
  998. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS
  999. Since: DOM Level 3
  1000. */
  1001. PHP_FUNCTION(dom_element_set_id_attribute_ns)
  1002. {
  1003. zval *id;
  1004. xmlNodePtr elemp;
  1005. xmlAttrPtr attrp;
  1006. dom_object *intern;
  1007. int uri_len, name_len;
  1008. char *uri, *name;
  1009. zend_bool is_id;
  1010. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossb", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &is_id) == FAILURE) {
  1011. return;
  1012. }
  1013. DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
  1014. if (dom_node_is_read_only(elemp) == SUCCESS) {
  1015. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  1016. RETURN_NULL();
  1017. }
  1018. attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
  1019. if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
  1020. php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  1021. } else {
  1022. php_set_attribute_id(attrp, is_id);
  1023. }
  1024. RETURN_NULL();
  1025. }
  1026. /* }}} end dom_element_set_id_attribute_ns */
  1027. /* {{{ proto void dom_element_set_id_attribute_node(attr idAttr, boolean isId);
  1028. URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode
  1029. Since: DOM Level 3
  1030. */
  1031. PHP_FUNCTION(dom_element_set_id_attribute_node)
  1032. {
  1033. zval *id, *node;
  1034. xmlNode *nodep;
  1035. xmlAttrPtr attrp;
  1036. dom_object *intern, *attrobj;
  1037. zend_bool is_id;
  1038. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOb", &id, dom_element_class_entry, &node, dom_attr_class_entry, &is_id) == FAILURE) {
  1039. return;
  1040. }
  1041. DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
  1042. if (dom_node_is_read_only(nodep) == SUCCESS) {
  1043. php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  1044. RETURN_NULL();
  1045. }
  1046. DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
  1047. if (attrp->parent != nodep) {
  1048. php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
  1049. } else {
  1050. php_set_attribute_id(attrp, is_id);
  1051. }
  1052. RETURN_NULL();
  1053. }
  1054. /* }}} end dom_element_set_id_attribute_node */
  1055. #endif
  1056. /*
  1057. * Local variables:
  1058. * tab-width: 4
  1059. * c-basic-offset: 4
  1060. * End:
  1061. * vim600: noet sw=4 ts=4 fdm=marker
  1062. * vim<600: noet sw=4 ts=4
  1063. */