element.c 35 KB

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