Annotation of embedaddon/php/ext/dom/node.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 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:
! 20: /* $Id: node.c 321634 2012-01-01 13:15:04Z felipe $ */
! 21:
! 22: #ifdef HAVE_CONFIG_H
! 23: #include "config.h"
! 24: #endif
! 25:
! 26: #include "php.h"
! 27: #if HAVE_LIBXML && HAVE_DOM
! 28: #include "php_dom.h"
! 29:
! 30: /* {{{ arginfo */
! 31: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1)
! 32: ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
! 33: ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1)
! 34: ZEND_END_ARG_INFO();
! 35:
! 36: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2)
! 37: ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
! 38: ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
! 39: ZEND_END_ARG_INFO();
! 40:
! 41: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1)
! 42: ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
! 43: ZEND_END_ARG_INFO();
! 44:
! 45: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1)
! 46: ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
! 47: ZEND_END_ARG_INFO();
! 48:
! 49: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0)
! 50: ZEND_END_ARG_INFO();
! 51:
! 52: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1)
! 53: ZEND_ARG_INFO(0, deep)
! 54: ZEND_END_ARG_INFO();
! 55:
! 56: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0)
! 57: ZEND_END_ARG_INFO();
! 58:
! 59: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2)
! 60: ZEND_ARG_INFO(0, feature)
! 61: ZEND_ARG_INFO(0, version)
! 62: ZEND_END_ARG_INFO();
! 63:
! 64: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0)
! 65: ZEND_END_ARG_INFO();
! 66:
! 67: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1)
! 68: ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
! 69: ZEND_END_ARG_INFO();
! 70:
! 71: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1)
! 72: ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
! 73: ZEND_END_ARG_INFO();
! 74:
! 75: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1)
! 76: ZEND_ARG_INFO(0, namespaceURI)
! 77: ZEND_END_ARG_INFO();
! 78:
! 79: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1)
! 80: ZEND_ARG_INFO(0, namespaceURI)
! 81: ZEND_END_ARG_INFO();
! 82:
! 83: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1)
! 84: ZEND_ARG_INFO(0, prefix)
! 85: ZEND_END_ARG_INFO();
! 86:
! 87: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1)
! 88: ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
! 89: ZEND_END_ARG_INFO();
! 90:
! 91: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2)
! 92: ZEND_ARG_INFO(0, feature)
! 93: ZEND_ARG_INFO(0, version)
! 94: ZEND_END_ARG_INFO();
! 95:
! 96: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3)
! 97: ZEND_ARG_INFO(0, key)
! 98: ZEND_ARG_INFO(0, data)
! 99: ZEND_ARG_INFO(0, handler)
! 100: ZEND_END_ARG_INFO();
! 101:
! 102: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1)
! 103: ZEND_ARG_INFO(0, key)
! 104: ZEND_END_ARG_INFO();
! 105:
! 106: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0)
! 107: ZEND_END_ARG_INFO();
! 108:
! 109: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getLineNo, 0, 0, 0)
! 110: ZEND_END_ARG_INFO();
! 111:
! 112: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0)
! 113: ZEND_ARG_INFO(0, exclusive)
! 114: ZEND_ARG_INFO(0, with_comments)
! 115: ZEND_ARG_ARRAY_INFO(0, xpath, 1)
! 116: ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
! 117: ZEND_END_ARG_INFO();
! 118:
! 119: ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1)
! 120: ZEND_ARG_INFO(0, uri)
! 121: ZEND_ARG_INFO(0, exclusive)
! 122: ZEND_ARG_INFO(0, with_comments)
! 123: ZEND_ARG_ARRAY_INFO(0, xpath, 1)
! 124: ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
! 125: ZEND_END_ARG_INFO();
! 126: /* }}} */
! 127:
! 128: /*
! 129: * class DOMNode
! 130: *
! 131: * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247
! 132: * Since:
! 133: */
! 134:
! 135: const zend_function_entry php_dom_node_class_functions[] = { /* {{{ */
! 136: PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before)
! 137: PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child)
! 138: PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child)
! 139: PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child)
! 140: PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes)
! 141: PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node)
! 142: PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize)
! 143: PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported)
! 144: PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes)
! 145: PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position)
! 146: PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node)
! 147: PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix)
! 148: PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace)
! 149: PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri)
! 150: PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node)
! 151: PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature)
! 152: PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data)
! 153: PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data)
! 154: PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC)
! 155: PHP_ME(domnode, getLineNo, arginfo_dom_node_getLineNo, ZEND_ACC_PUBLIC)
! 156: PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC)
! 157: PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC)
! 158: PHP_FE_END
! 159: };
! 160: /* }}} */
! 161:
! 162: static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
! 163: {
! 164: xmlNsPtr nsptr, nsdftptr, curns, prevns = NULL;
! 165:
! 166: if (nodep->type == XML_ELEMENT_NODE) {
! 167: /* Following if block primarily used for inserting nodes created via createElementNS */
! 168: if (nodep->nsDef != NULL) {
! 169: curns = nodep->nsDef;
! 170: while (curns) {
! 171: nsdftptr = curns->next;
! 172: if (curns->href != NULL) {
! 173: if((nsptr = xmlSearchNsByHref(doc, nodep->parent, curns->href)) &&
! 174: (curns->prefix == NULL || xmlStrEqual(nsptr->prefix, curns->prefix))) {
! 175: curns->next = NULL;
! 176: if (prevns == NULL) {
! 177: nodep->nsDef = nsdftptr;
! 178: } else {
! 179: prevns->next = nsdftptr;
! 180: }
! 181: dom_set_old_ns(doc, curns);
! 182: curns = prevns;
! 183: }
! 184: }
! 185: prevns = curns;
! 186: curns = nsdftptr;
! 187: }
! 188: }
! 189: xmlReconciliateNs(doc, nodep);
! 190: }
! 191: }
! 192: /* }}} */
! 193:
! 194: /* {{{ nodeName string
! 195: readonly=yes
! 196: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
! 197: Since:
! 198: */
! 199: int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
! 200: {
! 201: xmlNode *nodep;
! 202: xmlNsPtr ns;
! 203: char *str = NULL;
! 204: xmlChar *qname = NULL;
! 205:
! 206: nodep = dom_object_get_node(obj);
! 207:
! 208: if (nodep == NULL) {
! 209: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 210: return FAILURE;
! 211: }
! 212:
! 213: switch (nodep->type) {
! 214: case XML_ATTRIBUTE_NODE:
! 215: case XML_ELEMENT_NODE:
! 216: ns = nodep->ns;
! 217: if (ns != NULL && ns->prefix) {
! 218: qname = xmlStrdup(ns->prefix);
! 219: qname = xmlStrcat(qname, ":");
! 220: qname = xmlStrcat(qname, nodep->name);
! 221: str = qname;
! 222: } else {
! 223: str = (char *) nodep->name;
! 224: }
! 225: break;
! 226: case XML_NAMESPACE_DECL:
! 227: ns = nodep->ns;
! 228: if (ns != NULL && ns->prefix) {
! 229: qname = xmlStrdup("xmlns");
! 230: qname = xmlStrcat(qname, ":");
! 231: qname = xmlStrcat(qname, nodep->name);
! 232: str = qname;
! 233: } else {
! 234: str = (char *) nodep->name;
! 235: }
! 236: break;
! 237: case XML_DOCUMENT_TYPE_NODE:
! 238: case XML_DTD_NODE:
! 239: case XML_PI_NODE:
! 240: case XML_ENTITY_DECL:
! 241: case XML_ENTITY_REF_NODE:
! 242: case XML_NOTATION_NODE:
! 243: str = (char *) nodep->name;
! 244: break;
! 245: case XML_CDATA_SECTION_NODE:
! 246: str = "#cdata-section";
! 247: break;
! 248: case XML_COMMENT_NODE:
! 249: str = "#comment";
! 250: break;
! 251: case XML_HTML_DOCUMENT_NODE:
! 252: case XML_DOCUMENT_NODE:
! 253: str = "#document";
! 254: break;
! 255: case XML_DOCUMENT_FRAG_NODE:
! 256: str = "#document-fragment";
! 257: break;
! 258: case XML_TEXT_NODE:
! 259: str = "#text";
! 260: break;
! 261: default:
! 262: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type");
! 263: }
! 264:
! 265: ALLOC_ZVAL(*retval);
! 266:
! 267: if(str != NULL) {
! 268: ZVAL_STRING(*retval, str, 1);
! 269: } else {
! 270: ZVAL_EMPTY_STRING(*retval);
! 271: }
! 272:
! 273: if (qname != NULL) {
! 274: xmlFree(qname);
! 275: }
! 276:
! 277: return SUCCESS;
! 278:
! 279: }
! 280:
! 281: /* }}} */
! 282:
! 283: /* {{{ nodeValue string
! 284: readonly=no
! 285: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
! 286: Since:
! 287: */
! 288: int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC)
! 289: {
! 290: xmlNode *nodep;
! 291: char *str = NULL;
! 292:
! 293: nodep = dom_object_get_node(obj);
! 294:
! 295: if (nodep == NULL) {
! 296: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 297: return FAILURE;
! 298: }
! 299:
! 300: /* Access to Element node is implemented as a convience method */
! 301: switch (nodep->type) {
! 302: case XML_ATTRIBUTE_NODE:
! 303: case XML_TEXT_NODE:
! 304: case XML_ELEMENT_NODE:
! 305: case XML_COMMENT_NODE:
! 306: case XML_CDATA_SECTION_NODE:
! 307: case XML_PI_NODE:
! 308: str = xmlNodeGetContent(nodep);
! 309: break;
! 310: case XML_NAMESPACE_DECL:
! 311: str = xmlNodeGetContent(nodep->children);
! 312: break;
! 313: default:
! 314: str = NULL;
! 315: break;
! 316: }
! 317:
! 318: ALLOC_ZVAL(*retval);
! 319:
! 320: if(str != NULL) {
! 321: ZVAL_STRING(*retval, str, 1);
! 322: xmlFree(str);
! 323: } else {
! 324: ZVAL_NULL(*retval);
! 325: }
! 326:
! 327:
! 328: return SUCCESS;
! 329:
! 330: }
! 331:
! 332: int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
! 333: {
! 334: xmlNode *nodep;
! 335: zval value_copy;
! 336:
! 337: nodep = dom_object_get_node(obj);
! 338:
! 339: if (nodep == NULL) {
! 340: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 341: return FAILURE;
! 342: }
! 343:
! 344: /* Access to Element node is implemented as a convience method */
! 345: switch (nodep->type) {
! 346: case XML_ELEMENT_NODE:
! 347: case XML_ATTRIBUTE_NODE:
! 348: if (nodep->children) {
! 349: node_list_unlink(nodep->children TSRMLS_CC);
! 350: }
! 351: case XML_TEXT_NODE:
! 352: case XML_COMMENT_NODE:
! 353: case XML_CDATA_SECTION_NODE:
! 354: case XML_PI_NODE:
! 355: if (newval->type != IS_STRING) {
! 356: if(Z_REFCOUNT_P(newval) > 1) {
! 357: value_copy = *newval;
! 358: zval_copy_ctor(&value_copy);
! 359: newval = &value_copy;
! 360: }
! 361: convert_to_string(newval);
! 362: }
! 363: xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
! 364: if (newval == &value_copy) {
! 365: zval_dtor(newval);
! 366: }
! 367: break;
! 368: default:
! 369: break;
! 370: }
! 371:
! 372: return SUCCESS;
! 373: }
! 374:
! 375: /* }}} */
! 376:
! 377: /* {{{ nodeType int
! 378: readonly=yes
! 379: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558
! 380: Since:
! 381: */
! 382: int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC)
! 383: {
! 384: xmlNode *nodep;
! 385:
! 386: nodep = dom_object_get_node(obj);
! 387:
! 388: if (nodep == NULL) {
! 389: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 390: return FAILURE;
! 391: }
! 392:
! 393: ALLOC_ZVAL(*retval);
! 394:
! 395: /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */
! 396: if (nodep->type == XML_DTD_NODE) {
! 397: ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE);
! 398: } else {
! 399: ZVAL_LONG(*retval, nodep->type);
! 400: }
! 401:
! 402: return SUCCESS;
! 403: }
! 404:
! 405: /* }}} */
! 406:
! 407: /* {{{ parentNode DomNode
! 408: readonly=yes
! 409: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317
! 410: Since:
! 411: */
! 412: int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
! 413: {
! 414: xmlNode *nodep, *nodeparent;
! 415: int ret;
! 416:
! 417: nodep = dom_object_get_node(obj);
! 418:
! 419: if (nodep == NULL) {
! 420: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 421: return FAILURE;
! 422: }
! 423:
! 424: ALLOC_ZVAL(*retval);
! 425:
! 426: nodeparent = nodep->parent;
! 427: if (!nodeparent) {
! 428: ZVAL_NULL(*retval);
! 429: return SUCCESS;
! 430: }
! 431:
! 432: if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) {
! 433: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
! 434: return FAILURE;
! 435: }
! 436: return SUCCESS;
! 437: }
! 438:
! 439: /* }}} */
! 440:
! 441: /* {{{ childNodes DomNodeList
! 442: readonly=yes
! 443: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987
! 444: Since:
! 445: */
! 446: int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
! 447: {
! 448: xmlNode *nodep;
! 449: dom_object *intern;
! 450:
! 451: nodep = dom_object_get_node(obj);
! 452:
! 453: if (nodep == NULL) {
! 454: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 455: return FAILURE;
! 456: }
! 457:
! 458: ALLOC_ZVAL(*retval);
! 459:
! 460: if (dom_node_children_valid(nodep) == FAILURE) {
! 461: ZVAL_NULL(*retval);
! 462: } else {
! 463: php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
! 464: intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
! 465: dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
! 466: }
! 467:
! 468: return SUCCESS;
! 469: }
! 470:
! 471: /* }}} */
! 472:
! 473: /* {{{ firstChild DomNode
! 474: readonly=yes
! 475: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388
! 476: Since:
! 477: */
! 478: int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
! 479: {
! 480: xmlNode *nodep, *first = NULL;
! 481: int ret;
! 482:
! 483: nodep = dom_object_get_node(obj);
! 484:
! 485: if (nodep == NULL) {
! 486: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 487: return FAILURE;
! 488: }
! 489:
! 490: if (dom_node_children_valid(nodep) == SUCCESS) {
! 491: first = nodep->children;
! 492: }
! 493:
! 494: ALLOC_ZVAL(*retval);
! 495:
! 496: if (!first) {
! 497: ZVAL_NULL(*retval);
! 498: return SUCCESS;
! 499: }
! 500:
! 501: if (NULL == (*retval = php_dom_create_object(first, &ret, NULL, *retval, obj TSRMLS_CC))) {
! 502: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
! 503: return FAILURE;
! 504: }
! 505: return SUCCESS;
! 506: }
! 507:
! 508: /* }}} */
! 509:
! 510: /* {{{ lastChild DomNode
! 511: readonly=yes
! 512: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB
! 513: Since:
! 514: */
! 515: int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
! 516: {
! 517: xmlNode *nodep, *last = NULL;
! 518: int ret;
! 519:
! 520: nodep = dom_object_get_node(obj);
! 521:
! 522: if (nodep == NULL) {
! 523: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 524: return FAILURE;
! 525: }
! 526:
! 527: if (dom_node_children_valid(nodep) == SUCCESS) {
! 528: last = nodep->last;
! 529: }
! 530:
! 531: ALLOC_ZVAL(*retval);
! 532:
! 533: if (!last) {
! 534: ZVAL_NULL(*retval);
! 535: return SUCCESS;
! 536: }
! 537:
! 538: if (NULL == (*retval = php_dom_create_object(last, &ret, NULL, *retval, obj TSRMLS_CC))) {
! 539: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
! 540: return FAILURE;
! 541: }
! 542: return SUCCESS;
! 543: }
! 544:
! 545: /* }}} */
! 546:
! 547: /* {{{ previousSibling DomNode
! 548: readonly=yes
! 549: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8
! 550: Since:
! 551: */
! 552: int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
! 553: {
! 554: xmlNode *nodep, *prevsib;
! 555: int ret;
! 556:
! 557: nodep = dom_object_get_node(obj);
! 558:
! 559: if (nodep == NULL) {
! 560: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 561: return FAILURE;
! 562: }
! 563:
! 564: ALLOC_ZVAL(*retval);
! 565:
! 566: prevsib = nodep->prev;
! 567: if (!prevsib) {
! 568: ZVAL_NULL(*retval);
! 569: return SUCCESS;
! 570: }
! 571:
! 572: if (NULL == (*retval = php_dom_create_object(prevsib, &ret, NULL, *retval, obj TSRMLS_CC))) {
! 573: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
! 574: return FAILURE;
! 575: }
! 576: return SUCCESS;
! 577: }
! 578:
! 579: /* }}} */
! 580:
! 581: /* {{{ nextSibling DomNode
! 582: readonly=yes
! 583: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F
! 584: Since:
! 585: */
! 586: int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
! 587: {
! 588: xmlNode *nodep, *nextsib;
! 589: int ret;
! 590:
! 591: nodep = dom_object_get_node(obj);
! 592:
! 593: if (nodep == NULL) {
! 594: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 595: return FAILURE;
! 596: }
! 597:
! 598: nextsib = nodep->next;
! 599: if (!nextsib) {
! 600: return FAILURE;
! 601: }
! 602:
! 603: ALLOC_ZVAL(*retval);
! 604:
! 605: if (NULL == (*retval = php_dom_create_object(nextsib, &ret, NULL, *retval, obj TSRMLS_CC))) {
! 606: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
! 607: return FAILURE;
! 608: }
! 609: return SUCCESS;
! 610: }
! 611:
! 612: /* }}} */
! 613:
! 614: /* {{{ attributes DomNamedNodeMap
! 615: readonly=yes
! 616: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096
! 617: Since:
! 618: */
! 619: int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
! 620: {
! 621: xmlNode *nodep;
! 622: dom_object *intern;
! 623:
! 624: nodep = dom_object_get_node(obj);
! 625:
! 626: if (nodep == NULL) {
! 627: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 628: return FAILURE;
! 629: }
! 630:
! 631: ALLOC_ZVAL(*retval);
! 632:
! 633: if (nodep->type == XML_ELEMENT_NODE) {
! 634: php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
! 635: intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
! 636: dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
! 637: } else {
! 638: ZVAL_NULL(*retval);
! 639: }
! 640:
! 641: return SUCCESS;
! 642: }
! 643:
! 644: /* }}} */
! 645:
! 646: /* {{{ ownerDocument DomDocument
! 647: readonly=yes
! 648: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc
! 649: Since:
! 650: */
! 651: int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC)
! 652: {
! 653: xmlNode *nodep;
! 654: xmlDocPtr docp;
! 655: int ret;
! 656:
! 657: nodep = dom_object_get_node(obj);
! 658:
! 659: if (nodep == NULL) {
! 660: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 661: return FAILURE;
! 662: }
! 663:
! 664: if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
! 665: ALLOC_ZVAL(*retval);
! 666: ZVAL_NULL(*retval);
! 667: return SUCCESS;
! 668: }
! 669:
! 670: docp = nodep->doc;
! 671: if (!docp) {
! 672: return FAILURE;
! 673: }
! 674:
! 675: ALLOC_ZVAL(*retval);
! 676:
! 677: if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, NULL, *retval, obj TSRMLS_CC))) {
! 678: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
! 679: return FAILURE;
! 680: }
! 681: return SUCCESS;
! 682: }
! 683:
! 684: /* }}} */
! 685:
! 686: /* {{{ namespaceUri string
! 687: readonly=yes
! 688: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname
! 689: Since: DOM Level 2
! 690: */
! 691: int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
! 692: {
! 693: xmlNode *nodep;
! 694: char *str = NULL;
! 695:
! 696: nodep = dom_object_get_node(obj);
! 697:
! 698: if (nodep == NULL) {
! 699: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 700: return FAILURE;
! 701: }
! 702:
! 703: switch (nodep->type) {
! 704: case XML_ELEMENT_NODE:
! 705: case XML_ATTRIBUTE_NODE:
! 706: case XML_NAMESPACE_DECL:
! 707: if (nodep->ns != NULL) {
! 708: str = (char *) nodep->ns->href;
! 709: }
! 710: break;
! 711: default:
! 712: str = NULL;
! 713: break;
! 714: }
! 715:
! 716: ALLOC_ZVAL(*retval);
! 717:
! 718: if(str != NULL) {
! 719: ZVAL_STRING(*retval, str, 1);
! 720: } else {
! 721: ZVAL_NULL(*retval);
! 722: }
! 723:
! 724: return SUCCESS;
! 725: }
! 726:
! 727: /* }}} */
! 728:
! 729: /* {{{ prefix string
! 730: readonly=no
! 731: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
! 732: Since: DOM Level 2
! 733: */
! 734: int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC)
! 735: {
! 736: xmlNode *nodep;
! 737: xmlNsPtr ns;
! 738: char *str = NULL;
! 739:
! 740: nodep = dom_object_get_node(obj);
! 741:
! 742: if (nodep == NULL) {
! 743: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 744: return FAILURE;
! 745: }
! 746:
! 747: switch (nodep->type) {
! 748: case XML_ELEMENT_NODE:
! 749: case XML_ATTRIBUTE_NODE:
! 750: case XML_NAMESPACE_DECL:
! 751: ns = nodep->ns;
! 752: if (ns != NULL && ns->prefix) {
! 753: str = (char *) ns->prefix;
! 754: }
! 755: break;
! 756: default:
! 757: str = NULL;
! 758: break;
! 759: }
! 760:
! 761: ALLOC_ZVAL(*retval);
! 762:
! 763: if (str == NULL) {
! 764: ZVAL_EMPTY_STRING(*retval);
! 765: } else {
! 766: ZVAL_STRING(*retval, str, 1);
! 767: }
! 768: return SUCCESS;
! 769:
! 770: }
! 771:
! 772: int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
! 773: {
! 774: zval value_copy;
! 775: xmlNode *nodep, *nsnode = NULL;
! 776: xmlNsPtr ns = NULL, curns;
! 777: char *strURI;
! 778: char *prefix;
! 779:
! 780: nodep = dom_object_get_node(obj);
! 781:
! 782: if (nodep == NULL) {
! 783: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 784: return FAILURE;
! 785: }
! 786:
! 787: switch (nodep->type) {
! 788: case XML_ELEMENT_NODE:
! 789: nsnode = nodep;
! 790: case XML_ATTRIBUTE_NODE:
! 791: if (nsnode == NULL) {
! 792: nsnode = nodep->parent;
! 793: if (nsnode == NULL) {
! 794: nsnode = xmlDocGetRootElement(nodep->doc);
! 795: }
! 796: }
! 797: if (newval->type != IS_STRING) {
! 798: if(Z_REFCOUNT_P(newval) > 1) {
! 799: value_copy = *newval;
! 800: zval_copy_ctor(&value_copy);
! 801: newval = &value_copy;
! 802: }
! 803: convert_to_string(newval);
! 804: }
! 805: prefix = Z_STRVAL_P(newval);
! 806: if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
! 807: strURI = (char *) nodep->ns->href;
! 808: if (strURI == NULL ||
! 809: (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
! 810: (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
! 811: strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
! 812: (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
! 813: ns = NULL;
! 814: } else {
! 815: curns = nsnode->nsDef;
! 816: while (curns != NULL) {
! 817: if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) {
! 818: ns = curns;
! 819: break;
! 820: }
! 821: curns = curns->next;
! 822: }
! 823: if (ns == NULL) {
! 824: ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix);
! 825: }
! 826: }
! 827:
! 828: if (ns == NULL) {
! 829: if (newval == &value_copy) {
! 830: zval_dtor(newval);
! 831: }
! 832: php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC);
! 833: return FAILURE;
! 834: }
! 835:
! 836: xmlSetNs(nodep, ns);
! 837: }
! 838: if (newval == &value_copy) {
! 839: zval_dtor(newval);
! 840: }
! 841: break;
! 842: default:
! 843: break;
! 844: }
! 845:
! 846: return SUCCESS;
! 847: }
! 848:
! 849: /* }}} */
! 850:
! 851: /* {{{ localName string
! 852: readonly=yes
! 853: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN
! 854: Since: DOM Level 2
! 855: */
! 856: int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC)
! 857: {
! 858: xmlNode *nodep;
! 859:
! 860: nodep = dom_object_get_node(obj);
! 861:
! 862: if (nodep == NULL) {
! 863: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 864: return FAILURE;
! 865: }
! 866:
! 867: ALLOC_ZVAL(*retval);
! 868:
! 869: if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) {
! 870: ZVAL_STRING(*retval, (char *) (nodep->name), 1);
! 871: } else {
! 872: ZVAL_NULL(*retval);
! 873: }
! 874:
! 875: return SUCCESS;
! 876: }
! 877:
! 878: /* }}} */
! 879:
! 880: /* {{{ baseURI string
! 881: readonly=yes
! 882: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI
! 883: Since: DOM Level 3
! 884: */
! 885: int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
! 886: {
! 887: xmlNode *nodep;
! 888: xmlChar *baseuri;
! 889:
! 890: nodep = dom_object_get_node(obj);
! 891:
! 892: if (nodep == NULL) {
! 893: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 894: return FAILURE;
! 895: }
! 896:
! 897: ALLOC_ZVAL(*retval);
! 898:
! 899: baseuri = xmlNodeGetBase(nodep->doc, nodep);
! 900: if (baseuri) {
! 901: ZVAL_STRING(*retval, (char *) (baseuri), 1);
! 902: xmlFree(baseuri);
! 903: } else {
! 904: ZVAL_NULL(*retval);
! 905: }
! 906:
! 907: return SUCCESS;
! 908: }
! 909:
! 910: /* }}} */
! 911:
! 912: /* {{{ textContent string
! 913: readonly=no
! 914: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
! 915: Since: DOM Level 3
! 916: */
! 917: int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
! 918: {
! 919: xmlNode *nodep;
! 920: char *str = NULL;
! 921:
! 922: nodep = dom_object_get_node(obj);
! 923:
! 924: if (nodep == NULL) {
! 925: php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
! 926: return FAILURE;
! 927: }
! 928:
! 929: str = xmlNodeGetContent(nodep);
! 930:
! 931: ALLOC_ZVAL(*retval);
! 932:
! 933: if(str != NULL) {
! 934: ZVAL_STRING(*retval, str, 1);
! 935: xmlFree(str);
! 936: } else {
! 937: ZVAL_EMPTY_STRING(*retval);
! 938: }
! 939:
! 940: return SUCCESS;
! 941: }
! 942:
! 943: int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
! 944: {
! 945: return SUCCESS;
! 946: }
! 947:
! 948: /* }}} */
! 949:
! 950: static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlNodePtr nextsib, xmlNodePtr fragment, dom_object *intern, dom_object *childobj TSRMLS_DC) /* {{{ */
! 951: {
! 952: xmlNodePtr newchild, node;
! 953:
! 954: newchild = fragment->children;
! 955:
! 956: if (newchild) {
! 957: if (prevsib == NULL) {
! 958: nodep->children = newchild;
! 959: } else {
! 960: prevsib->next = newchild;
! 961: }
! 962: newchild->prev = prevsib;
! 963: if (nextsib == NULL) {
! 964: nodep->last = fragment->last;
! 965: } else {
! 966: fragment->last->next = nextsib;
! 967: nextsib->prev = fragment->last;
! 968: }
! 969:
! 970: node = newchild;
! 971: while (node != NULL) {
! 972: node->parent = nodep;
! 973: if (node->doc != nodep->doc) {
! 974: xmlSetTreeDoc(node, nodep->doc);
! 975: if (node->_private != NULL) {
! 976: childobj = node->_private;
! 977: childobj->document = intern->document;
! 978: php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
! 979: }
! 980: }
! 981: if (node == fragment->last) {
! 982: break;
! 983: }
! 984: node = node->next;
! 985: }
! 986:
! 987: fragment->children = NULL;
! 988: fragment->last = NULL;
! 989: }
! 990:
! 991: return newchild;
! 992: }
! 993: /* }}} */
! 994:
! 995: /* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild);
! 996: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
! 997: Since:
! 998: */
! 999: PHP_FUNCTION(dom_node_insert_before)
! 1000: {
! 1001: zval *id, *node, *ref = NULL;
! 1002: xmlNodePtr child, new_child, parentp, refp;
! 1003: dom_object *intern, *childobj, *refpobj;
! 1004: int ret, stricterror;
! 1005:
! 1006: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|O!", &id, dom_node_class_entry, &node, dom_node_class_entry, &ref, dom_node_class_entry) == FAILURE) {
! 1007: return;
! 1008: }
! 1009:
! 1010: DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
! 1011:
! 1012: if (dom_node_children_valid(parentp) == FAILURE) {
! 1013: RETURN_FALSE;
! 1014: }
! 1015:
! 1016: DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
! 1017:
! 1018: new_child = NULL;
! 1019:
! 1020: stricterror = dom_get_strict_error(intern->document);
! 1021:
! 1022: if (dom_node_is_read_only(parentp) == SUCCESS ||
! 1023: (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
! 1024: php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
! 1025: RETURN_FALSE;
! 1026: }
! 1027:
! 1028: if (dom_hierarchy(parentp, child) == FAILURE) {
! 1029: php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
! 1030: RETURN_FALSE;
! 1031: }
! 1032:
! 1033: if (child->doc != parentp->doc && child->doc != NULL) {
! 1034: php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
! 1035: RETURN_FALSE;
! 1036: }
! 1037:
! 1038: if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
! 1039: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
! 1040: RETURN_FALSE;
! 1041: }
! 1042:
! 1043: if (child->doc == NULL && parentp->doc != NULL) {
! 1044: childobj->document = intern->document;
! 1045: php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
! 1046: }
! 1047:
! 1048: if (ref != NULL) {
! 1049: DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
! 1050: if (refp->parent != parentp) {
! 1051: php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
! 1052: RETURN_FALSE;
! 1053: }
! 1054:
! 1055: if (child->parent != NULL) {
! 1056: xmlUnlinkNode(child);
! 1057: }
! 1058:
! 1059: if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE ||
! 1060: (refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) {
! 1061: if (child->doc == NULL) {
! 1062: xmlSetTreeDoc(child, parentp->doc);
! 1063: }
! 1064: new_child = child;
! 1065: new_child->parent = refp->parent;
! 1066: new_child->next = refp;
! 1067: new_child->prev = refp->prev;
! 1068: refp->prev = new_child;
! 1069: if (new_child->prev != NULL) {
! 1070: new_child->prev->next = new_child;
! 1071: }
! 1072: if (new_child->parent != NULL) {
! 1073: if (new_child->parent->children == refp) {
! 1074: new_child->parent->children = new_child;
! 1075: }
! 1076: }
! 1077:
! 1078: } else if (child->type == XML_ATTRIBUTE_NODE) {
! 1079: xmlAttrPtr lastattr;
! 1080:
! 1081: if (child->ns == NULL)
! 1082: lastattr = xmlHasProp(refp->parent, child->name);
! 1083: else
! 1084: lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
! 1085: if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
! 1086: if (lastattr != (xmlAttrPtr) child) {
! 1087: xmlUnlinkNode((xmlNodePtr) lastattr);
! 1088: php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
! 1089: } else {
! 1090: DOM_RET_OBJ_EX(child, &ret, intern);
! 1091: return;
! 1092: }
! 1093: }
! 1094: } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
! 1095: new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC);
! 1096: }
! 1097:
! 1098: if (new_child == NULL) {
! 1099: new_child = xmlAddPrevSibling(refp, child);
! 1100: }
! 1101: } else {
! 1102: if (child->parent != NULL){
! 1103: xmlUnlinkNode(child);
! 1104: }
! 1105: if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) {
! 1106: child->parent = parentp;
! 1107: if (child->doc == NULL) {
! 1108: xmlSetTreeDoc(child, parentp->doc);
! 1109: }
! 1110: new_child = child;
! 1111: if (parentp->children == NULL) {
! 1112: parentp->children = child;
! 1113: parentp->last = child;
! 1114: } else {
! 1115: child = parentp->last;
! 1116: child->next = new_child;
! 1117: new_child->prev = child;
! 1118: parentp->last = new_child;
! 1119: }
! 1120: } else if (child->type == XML_ATTRIBUTE_NODE) {
! 1121: xmlAttrPtr lastattr;
! 1122:
! 1123: if (child->ns == NULL)
! 1124: lastattr = xmlHasProp(parentp, child->name);
! 1125: else
! 1126: lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
! 1127: if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
! 1128: if (lastattr != (xmlAttrPtr) child) {
! 1129: xmlUnlinkNode((xmlNodePtr) lastattr);
! 1130: php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
! 1131: } else {
! 1132: DOM_RET_OBJ_EX(child, &ret, intern);
! 1133: return;
! 1134: }
! 1135: }
! 1136: } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
! 1137: new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC);
! 1138: }
! 1139: if (new_child == NULL) {
! 1140: new_child = xmlAddChild(parentp, child);
! 1141: }
! 1142: }
! 1143:
! 1144: if (NULL == new_child) {
! 1145: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode");
! 1146: RETURN_FALSE;
! 1147: }
! 1148:
! 1149: dom_reconcile_ns(parentp->doc, new_child);
! 1150:
! 1151: DOM_RET_OBJ_EX(new_child, &ret, intern);
! 1152:
! 1153: }
! 1154: /* }}} end dom_node_insert_before */
! 1155:
! 1156: /* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);
! 1157: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
! 1158: Since:
! 1159: */
! 1160: PHP_FUNCTION(dom_node_replace_child)
! 1161: {
! 1162: zval *id, *newnode, *oldnode;
! 1163: xmlNodePtr children, newchild, oldchild, nodep;
! 1164: dom_object *intern, *newchildobj, *oldchildobj;
! 1165: int foundoldchild = 0, stricterror;
! 1166:
! 1167: int ret;
! 1168:
! 1169: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOO", &id, dom_node_class_entry, &newnode, dom_node_class_entry, &oldnode, dom_node_class_entry) == FAILURE) {
! 1170: return;
! 1171: }
! 1172:
! 1173: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1174:
! 1175: if (dom_node_children_valid(nodep) == FAILURE) {
! 1176: RETURN_FALSE;
! 1177: }
! 1178:
! 1179: DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
! 1180: DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
! 1181:
! 1182: children = nodep->children;
! 1183: if (!children) {
! 1184: RETURN_FALSE;
! 1185: }
! 1186:
! 1187: stricterror = dom_get_strict_error(intern->document);
! 1188:
! 1189: if (dom_node_is_read_only(nodep) == SUCCESS ||
! 1190: (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
! 1191: php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
! 1192: RETURN_FALSE;
! 1193: }
! 1194:
! 1195: if (newchild->doc != nodep->doc && newchild->doc != NULL) {
! 1196: php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
! 1197: RETURN_FALSE;
! 1198: }
! 1199:
! 1200: if (dom_hierarchy(nodep, newchild) == FAILURE) {
! 1201: php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
! 1202: RETURN_FALSE;
! 1203: }
! 1204:
! 1205: /* check for the old child and whether the new child is already a child */
! 1206: while (children) {
! 1207: if (children == oldchild) {
! 1208: foundoldchild = 1;
! 1209: break;
! 1210: }
! 1211: children = children->next;
! 1212: }
! 1213:
! 1214: if (foundoldchild) {
! 1215: if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
! 1216: xmlNodePtr prevsib, nextsib;
! 1217: prevsib = oldchild->prev;
! 1218: nextsib = oldchild->next;
! 1219:
! 1220: xmlUnlinkNode(oldchild);
! 1221:
! 1222: newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC);
! 1223: if (newchild) {
! 1224: dom_reconcile_ns(nodep->doc, newchild);
! 1225: }
! 1226: } else if (oldchild != newchild) {
! 1227: if (newchild->doc == NULL && nodep->doc != NULL) {
! 1228: xmlSetTreeDoc(newchild, nodep->doc);
! 1229: newchildobj->document = intern->document;
! 1230: php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
! 1231: }
! 1232: xmlReplaceNode(oldchild, newchild);
! 1233: dom_reconcile_ns(nodep->doc, newchild);
! 1234: }
! 1235: DOM_RET_OBJ_EX(oldchild, &ret, intern);
! 1236: return;
! 1237: } else {
! 1238: php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
! 1239: RETURN_FALSE;
! 1240: }
! 1241: }
! 1242: /* }}} end dom_node_replace_child */
! 1243:
! 1244: /* {{{ proto DomNode dom_node_remove_child(DomNode oldChild);
! 1245: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
! 1246: Since:
! 1247: */
! 1248: PHP_FUNCTION(dom_node_remove_child)
! 1249: {
! 1250: zval *id, *node;
! 1251: xmlNodePtr children, child, nodep;
! 1252: dom_object *intern, *childobj;
! 1253: int ret, stricterror;
! 1254:
! 1255: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
! 1256: return;
! 1257: }
! 1258:
! 1259: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1260:
! 1261: if (dom_node_children_valid(nodep) == FAILURE) {
! 1262: RETURN_FALSE;
! 1263: }
! 1264:
! 1265: DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
! 1266:
! 1267: stricterror = dom_get_strict_error(intern->document);
! 1268:
! 1269: if (dom_node_is_read_only(nodep) == SUCCESS ||
! 1270: (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
! 1271: php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
! 1272: RETURN_FALSE;
! 1273: }
! 1274:
! 1275: children = nodep->children;
! 1276: if (!children) {
! 1277: php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
! 1278: RETURN_FALSE;
! 1279: }
! 1280:
! 1281: while (children) {
! 1282: if (children == child) {
! 1283: xmlUnlinkNode(child);
! 1284: DOM_RET_OBJ_EX(child, &ret, intern);
! 1285: return;
! 1286: }
! 1287: children = children->next;
! 1288: }
! 1289:
! 1290: php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
! 1291: RETURN_FALSE
! 1292: }
! 1293: /* }}} end dom_node_remove_child */
! 1294:
! 1295: /* {{{ proto DomNode dom_node_append_child(DomNode newChild);
! 1296: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
! 1297: Since:
! 1298: */
! 1299: PHP_FUNCTION(dom_node_append_child)
! 1300: {
! 1301: zval *id, *node;
! 1302: xmlNodePtr child, nodep, new_child = NULL;
! 1303: dom_object *intern, *childobj;
! 1304: int ret, stricterror;
! 1305:
! 1306: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
! 1307: return;
! 1308: }
! 1309:
! 1310: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1311:
! 1312: if (dom_node_children_valid(nodep) == FAILURE) {
! 1313: RETURN_FALSE;
! 1314: }
! 1315:
! 1316: DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
! 1317:
! 1318: stricterror = dom_get_strict_error(intern->document);
! 1319:
! 1320: if (dom_node_is_read_only(nodep) == SUCCESS ||
! 1321: (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
! 1322: php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
! 1323: RETURN_FALSE;
! 1324: }
! 1325:
! 1326: if (dom_hierarchy(nodep, child) == FAILURE) {
! 1327: php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
! 1328: RETURN_FALSE;
! 1329: }
! 1330:
! 1331: if (!(child->doc == NULL || child->doc == nodep->doc)) {
! 1332: php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
! 1333: RETURN_FALSE;
! 1334: }
! 1335:
! 1336: if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
! 1337: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
! 1338: RETURN_FALSE;
! 1339: }
! 1340:
! 1341: if (child->doc == NULL && nodep->doc != NULL) {
! 1342: childobj->document = intern->document;
! 1343: php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
! 1344: }
! 1345:
! 1346: if (child->parent != NULL){
! 1347: xmlUnlinkNode(child);
! 1348: }
! 1349:
! 1350: if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) {
! 1351: child->parent = nodep;
! 1352: if (child->doc == NULL) {
! 1353: xmlSetTreeDoc(child, nodep->doc);
! 1354: }
! 1355: new_child = child;
! 1356: if (nodep->children == NULL) {
! 1357: nodep->children = child;
! 1358: nodep->last = child;
! 1359: } else {
! 1360: child = nodep->last;
! 1361: child->next = new_child;
! 1362: new_child->prev = child;
! 1363: nodep->last = new_child;
! 1364: }
! 1365: } else if (child->type == XML_ATTRIBUTE_NODE) {
! 1366: xmlAttrPtr lastattr;
! 1367:
! 1368: if (child->ns == NULL)
! 1369: lastattr = xmlHasProp(nodep, child->name);
! 1370: else
! 1371: lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
! 1372: if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
! 1373: if (lastattr != (xmlAttrPtr) child) {
! 1374: xmlUnlinkNode((xmlNodePtr) lastattr);
! 1375: php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
! 1376: }
! 1377: }
! 1378: } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
! 1379: new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC);
! 1380: }
! 1381:
! 1382: if (new_child == NULL) {
! 1383: new_child = xmlAddChild(nodep, child);
! 1384: if (new_child == NULL) {
! 1385: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node");
! 1386: RETURN_FALSE;
! 1387: }
! 1388: }
! 1389:
! 1390: dom_reconcile_ns(nodep->doc, new_child);
! 1391:
! 1392: DOM_RET_OBJ_EX(new_child, &ret, intern);
! 1393: }
! 1394: /* }}} end dom_node_append_child */
! 1395:
! 1396: /* {{{ proto boolean dom_node_has_child_nodes();
! 1397: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
! 1398: Since:
! 1399: */
! 1400: PHP_FUNCTION(dom_node_has_child_nodes)
! 1401: {
! 1402: zval *id;
! 1403: xmlNode *nodep;
! 1404: dom_object *intern;
! 1405:
! 1406: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
! 1407: return;
! 1408: }
! 1409:
! 1410: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1411:
! 1412: if (dom_node_children_valid(nodep) == FAILURE) {
! 1413: RETURN_FALSE;
! 1414: }
! 1415:
! 1416: if (nodep->children) {
! 1417: RETURN_TRUE;
! 1418: } else {
! 1419: RETURN_FALSE;
! 1420: }
! 1421: }
! 1422: /* }}} end dom_node_has_child_nodes */
! 1423:
! 1424: /* {{{ proto DomNode dom_node_clone_node(boolean deep);
! 1425: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4
! 1426: Since:
! 1427: */
! 1428: PHP_FUNCTION(dom_node_clone_node)
! 1429: {
! 1430: zval *id;
! 1431: xmlNode *n, *node;
! 1432: int ret;
! 1433: dom_object *intern;
! 1434: long recursive = 0;
! 1435:
! 1436: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
! 1437: return;
! 1438: }
! 1439:
! 1440: DOM_GET_OBJ(n, id, xmlNodePtr, intern);
! 1441:
! 1442: node = xmlDocCopyNode(n, n->doc, recursive);
! 1443:
! 1444: if (!node) {
! 1445: RETURN_FALSE;
! 1446: }
! 1447:
! 1448: /* When deep is false Element nodes still require the attributes
! 1449: Following taken from libxml as xmlDocCopyNode doesnt do this */
! 1450: if (n->type == XML_ELEMENT_NODE && recursive == 0) {
! 1451: if (n->nsDef != NULL) {
! 1452: node->nsDef = xmlCopyNamespaceList(n->nsDef);
! 1453: }
! 1454: if (n->ns != NULL) {
! 1455: xmlNsPtr ns;
! 1456: ns = xmlSearchNs(n->doc, node, n->ns->prefix);
! 1457: if (ns == NULL) {
! 1458: ns = xmlSearchNs(n->doc, n, n->ns->prefix);
! 1459: if (ns != NULL) {
! 1460: xmlNodePtr root = node;
! 1461:
! 1462: while (root->parent != NULL) {
! 1463: root = root->parent;
! 1464: }
! 1465: node->ns = xmlNewNs(root, ns->href, ns->prefix);
! 1466: }
! 1467: } else {
! 1468: node->ns = ns;
! 1469: }
! 1470: }
! 1471: if (n->properties != NULL) {
! 1472: node->properties = xmlCopyPropList(node, n->properties);
! 1473: }
! 1474: }
! 1475:
! 1476: /* If document cloned we want a new document proxy */
! 1477: if (node->doc != n->doc) {
! 1478: intern = NULL;
! 1479: }
! 1480:
! 1481: DOM_RET_OBJ_EX(node, &ret, intern);
! 1482: }
! 1483: /* }}} end dom_node_clone_node */
! 1484:
! 1485: /* {{{ proto void dom_node_normalize();
! 1486: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize
! 1487: Since:
! 1488: */
! 1489: PHP_FUNCTION(dom_node_normalize)
! 1490: {
! 1491: zval *id;
! 1492: xmlNode *nodep;
! 1493: dom_object *intern;
! 1494:
! 1495: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
! 1496: return;
! 1497: }
! 1498:
! 1499: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1500:
! 1501: dom_normalize(nodep TSRMLS_CC);
! 1502:
! 1503: }
! 1504: /* }}} end dom_node_normalize */
! 1505:
! 1506: /* {{{ proto boolean dom_node_is_supported(string feature, string version);
! 1507: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports
! 1508: Since: DOM Level 2
! 1509: */
! 1510: PHP_FUNCTION(dom_node_is_supported)
! 1511: {
! 1512: zval *id;
! 1513: int feature_len, version_len;
! 1514: char *feature, *version;
! 1515:
! 1516: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) {
! 1517: return;
! 1518: }
! 1519:
! 1520: if (dom_has_feature(feature, version)) {
! 1521: RETURN_TRUE;
! 1522: } else {
! 1523: RETURN_FALSE;
! 1524: }
! 1525: }
! 1526: /* }}} end dom_node_is_supported */
! 1527:
! 1528: /* {{{ proto boolean dom_node_has_attributes();
! 1529: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs
! 1530: Since: DOM Level 2
! 1531: */
! 1532: PHP_FUNCTION(dom_node_has_attributes)
! 1533: {
! 1534: zval *id;
! 1535: xmlNode *nodep;
! 1536: dom_object *intern;
! 1537:
! 1538: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
! 1539: return;
! 1540: }
! 1541:
! 1542: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1543:
! 1544: if (nodep->type != XML_ELEMENT_NODE)
! 1545: RETURN_FALSE;
! 1546:
! 1547: if (nodep->properties) {
! 1548: RETURN_TRUE;
! 1549: } else {
! 1550: RETURN_FALSE;
! 1551: }
! 1552: }
! 1553: /* }}} end dom_node_has_attributes */
! 1554:
! 1555: /* {{{ proto short dom_node_compare_document_position(DomNode other);
! 1556: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition
! 1557: Since: DOM Level 3
! 1558: */
! 1559: PHP_FUNCTION(dom_node_compare_document_position)
! 1560: {
! 1561: DOM_NOT_IMPLEMENTED();
! 1562: }
! 1563: /* }}} end dom_node_compare_document_position */
! 1564:
! 1565: /* {{{ proto boolean dom_node_is_same_node(DomNode other);
! 1566: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
! 1567: Since: DOM Level 3
! 1568: */
! 1569: PHP_FUNCTION(dom_node_is_same_node)
! 1570: {
! 1571: zval *id, *node;
! 1572: xmlNodePtr nodeotherp, nodep;
! 1573: dom_object *intern, *nodeotherobj;
! 1574:
! 1575: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
! 1576: return;
! 1577: }
! 1578:
! 1579: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1580:
! 1581: DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
! 1582:
! 1583: if (nodep == nodeotherp) {
! 1584: RETURN_TRUE;
! 1585: } else {
! 1586: RETURN_FALSE;
! 1587: }
! 1588: }
! 1589: /* }}} end dom_node_is_same_node */
! 1590:
! 1591: /* {{{ proto string dom_node_lookup_prefix(string namespaceURI);
! 1592: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
! 1593: Since: DOM Level 3
! 1594: */
! 1595: PHP_FUNCTION(dom_node_lookup_prefix)
! 1596: {
! 1597: zval *id;
! 1598: xmlNodePtr nodep, lookupp = NULL;
! 1599: dom_object *intern;
! 1600: xmlNsPtr nsptr;
! 1601: int uri_len = 0;
! 1602: char *uri;
! 1603:
! 1604: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
! 1605: return;
! 1606: }
! 1607:
! 1608: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1609:
! 1610: if (uri_len > 0) {
! 1611: switch (nodep->type) {
! 1612: case XML_ELEMENT_NODE:
! 1613: lookupp = nodep;
! 1614: break;
! 1615: case XML_DOCUMENT_NODE:
! 1616: case XML_HTML_DOCUMENT_NODE:
! 1617: lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
! 1618: break;
! 1619: case XML_ENTITY_NODE :
! 1620: case XML_NOTATION_NODE:
! 1621: case XML_DOCUMENT_FRAG_NODE:
! 1622: case XML_DOCUMENT_TYPE_NODE:
! 1623: case XML_DTD_NODE:
! 1624: RETURN_NULL();
! 1625: break;
! 1626: default:
! 1627: lookupp = nodep->parent;
! 1628: }
! 1629:
! 1630: if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
! 1631: if (nsptr->prefix != NULL) {
! 1632: RETURN_STRING((char *) nsptr->prefix, 1);
! 1633: }
! 1634: }
! 1635: }
! 1636:
! 1637: RETURN_NULL();
! 1638: }
! 1639: /* }}} end dom_node_lookup_prefix */
! 1640:
! 1641: /* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI);
! 1642: URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
! 1643: Since: DOM Level 3
! 1644: */
! 1645: PHP_FUNCTION(dom_node_is_default_namespace)
! 1646: {
! 1647: zval *id;
! 1648: xmlNodePtr nodep;
! 1649: dom_object *intern;
! 1650: xmlNsPtr nsptr;
! 1651: int uri_len = 0;
! 1652: char *uri;
! 1653:
! 1654: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
! 1655: return;
! 1656: }
! 1657:
! 1658: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1659: if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
! 1660: nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
! 1661: }
! 1662:
! 1663: if (nodep && uri_len > 0) {
! 1664: nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
! 1665: if (nsptr && xmlStrEqual(nsptr->href, uri)) {
! 1666: RETURN_TRUE;
! 1667: }
! 1668: }
! 1669:
! 1670: RETURN_FALSE;
! 1671: }
! 1672: /* }}} end dom_node_is_default_namespace */
! 1673:
! 1674: /* {{{ proto string dom_node_lookup_namespace_uri(string prefix);
! 1675: URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
! 1676: Since: DOM Level 3
! 1677: */
! 1678: PHP_FUNCTION(dom_node_lookup_namespace_uri)
! 1679: {
! 1680: zval *id;
! 1681: xmlNodePtr nodep;
! 1682: dom_object *intern;
! 1683: xmlNsPtr nsptr;
! 1684: int prefix_len = 0;
! 1685: char *prefix=NULL;
! 1686:
! 1687: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) {
! 1688: return;
! 1689: }
! 1690:
! 1691: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1692: if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
! 1693: nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
! 1694: if (nodep == NULL) {
! 1695: RETURN_NULL();
! 1696: }
! 1697: }
! 1698:
! 1699: nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
! 1700: if (nsptr && nsptr->href != NULL) {
! 1701: RETURN_STRING((char *) nsptr->href, 1);
! 1702: }
! 1703:
! 1704: RETURN_NULL();
! 1705: }
! 1706: /* }}} end dom_node_lookup_namespace_uri */
! 1707:
! 1708: /* {{{ proto boolean dom_node_is_equal_node(DomNode arg);
! 1709: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode
! 1710: Since: DOM Level 3
! 1711: */
! 1712: PHP_FUNCTION(dom_node_is_equal_node)
! 1713: {
! 1714: DOM_NOT_IMPLEMENTED();
! 1715: }
! 1716: /* }}} end dom_node_is_equal_node */
! 1717:
! 1718: /* {{{ proto DomNode dom_node_get_feature(string feature, string version);
! 1719: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature
! 1720: Since: DOM Level 3
! 1721: */
! 1722: PHP_FUNCTION(dom_node_get_feature)
! 1723: {
! 1724: DOM_NOT_IMPLEMENTED();
! 1725: }
! 1726: /* }}} end dom_node_get_feature */
! 1727:
! 1728: /* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);
! 1729: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData
! 1730: Since: DOM Level 3
! 1731: */
! 1732: PHP_FUNCTION(dom_node_set_user_data)
! 1733: {
! 1734: DOM_NOT_IMPLEMENTED();
! 1735: }
! 1736: /* }}} end dom_node_set_user_data */
! 1737:
! 1738: /* {{{ proto mixed dom_node_get_user_data(string key);
! 1739: URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData
! 1740: Since: DOM Level 3
! 1741: */
! 1742: PHP_FUNCTION(dom_node_get_user_data)
! 1743: {
! 1744: DOM_NOT_IMPLEMENTED();
! 1745: }
! 1746: /* }}} end dom_node_get_user_data */
! 1747:
! 1748: static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
! 1749: {
! 1750: zval *id;
! 1751: zval *xpath_array=NULL, *ns_prefixes=NULL;
! 1752: xmlNodePtr nodep;
! 1753: xmlDocPtr docp;
! 1754: xmlNodeSetPtr nodeset = NULL;
! 1755: dom_object *intern;
! 1756: zend_bool exclusive=0, with_comments=0;
! 1757: xmlChar **inclusive_ns_prefixes = NULL;
! 1758: char *file = NULL;
! 1759: int ret = -1, file_len = 0;
! 1760: xmlOutputBufferPtr buf;
! 1761: xmlXPathContextPtr ctxp=NULL;
! 1762: xmlXPathObjectPtr xpathobjp=NULL;
! 1763:
! 1764: if (mode == 0) {
! 1765: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
! 1766: "O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments,
! 1767: &xpath_array, &ns_prefixes) == FAILURE) {
! 1768: return;
! 1769: }
! 1770: } else {
! 1771: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
! 1772: "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive,
! 1773: &with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
! 1774: return;
! 1775: }
! 1776: }
! 1777:
! 1778: DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
! 1779:
! 1780: docp = nodep->doc;
! 1781:
! 1782: if (! docp) {
! 1783: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document");
! 1784: RETURN_FALSE;
! 1785: }
! 1786:
! 1787: if (xpath_array == NULL) {
! 1788: if (nodep->type != XML_DOCUMENT_NODE) {
! 1789: ctxp = xmlXPathNewContext(docp);
! 1790: ctxp->node = nodep;
! 1791: xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp);
! 1792: ctxp->node = NULL;
! 1793: if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
! 1794: nodeset = xpathobjp->nodesetval;
! 1795: } else {
! 1796: if (xpathobjp) {
! 1797: xmlXPathFreeObject(xpathobjp);
! 1798: }
! 1799: xmlXPathFreeContext(ctxp);
! 1800: php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
! 1801: RETURN_FALSE;
! 1802: }
! 1803: }
! 1804: } else {
! 1805: /*xpath query from xpath_array */
! 1806: HashTable *ht = Z_ARRVAL_P(xpath_array);
! 1807: zval **tmp;
! 1808: char *xquery;
! 1809:
! 1810: if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS &&
! 1811: Z_TYPE_PP(tmp) == IS_STRING) {
! 1812: xquery = Z_STRVAL_PP(tmp);
! 1813: } else {
! 1814: php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string");
! 1815: RETURN_FALSE;
! 1816: }
! 1817:
! 1818: ctxp = xmlXPathNewContext(docp);
! 1819: ctxp->node = nodep;
! 1820:
! 1821: if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS &&
! 1822: Z_TYPE_PP(tmp) == IS_ARRAY) {
! 1823: zval **tmpns;
! 1824: while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) {
! 1825: if (Z_TYPE_PP(tmpns) == IS_STRING) {
! 1826: char *prefix;
! 1827: ulong idx;
! 1828: int prefix_key_len;
! 1829:
! 1830: if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp),
! 1831: &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
! 1832: xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns));
! 1833: }
! 1834: }
! 1835: zend_hash_move_forward(Z_ARRVAL_PP(tmp));
! 1836: }
! 1837: }
! 1838:
! 1839: xpathobjp = xmlXPathEvalExpression(xquery, ctxp);
! 1840: ctxp->node = NULL;
! 1841: if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
! 1842: nodeset = xpathobjp->nodesetval;
! 1843: } else {
! 1844: if (xpathobjp) {
! 1845: xmlXPathFreeObject(xpathobjp);
! 1846: }
! 1847: xmlXPathFreeContext(ctxp);
! 1848: php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
! 1849: RETURN_FALSE;
! 1850: }
! 1851: }
! 1852:
! 1853: if (ns_prefixes != NULL) {
! 1854: if (exclusive) {
! 1855: zval **tmpns;
! 1856: int nscount = 0;
! 1857:
! 1858: inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1,
! 1859: sizeof(xmlChar *), 0);
! 1860: while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) {
! 1861: if (Z_TYPE_PP(tmpns) == IS_STRING) {
! 1862: inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns);
! 1863: }
! 1864: zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes));
! 1865: }
! 1866: inclusive_ns_prefixes[nscount] = NULL;
! 1867: } else {
! 1868: php_error_docref(NULL TSRMLS_CC, E_NOTICE,
! 1869: "Inclusive namespace prefixes only allowed in exclusive mode.");
! 1870: }
! 1871: }
! 1872:
! 1873: if (mode == 1) {
! 1874: buf = xmlOutputBufferCreateFilename(file, NULL, 0);
! 1875: } else {
! 1876: buf = xmlAllocOutputBuffer(NULL);
! 1877: }
! 1878:
! 1879: if (buf != NULL) {
! 1880: ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
! 1881: with_comments, buf);
! 1882: }
! 1883:
! 1884: if (inclusive_ns_prefixes != NULL) {
! 1885: efree(inclusive_ns_prefixes);
! 1886: }
! 1887: if (xpathobjp != NULL) {
! 1888: xmlXPathFreeObject(xpathobjp);
! 1889: }
! 1890: if (ctxp != NULL) {
! 1891: xmlXPathFreeContext(ctxp);
! 1892: }
! 1893:
! 1894: if (buf == NULL || ret < 0) {
! 1895: RETVAL_FALSE;
! 1896: } else {
! 1897: if (mode == 0) {
! 1898: ret = buf->buffer->use;
! 1899: if (ret > 0) {
! 1900: RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
! 1901: } else {
! 1902: RETVAL_EMPTY_STRING();
! 1903: }
! 1904: }
! 1905: }
! 1906:
! 1907: if (buf) {
! 1908: int bytes;
! 1909:
! 1910: bytes = xmlOutputBufferClose(buf);
! 1911: if (mode == 1 && (ret >= 0)) {
! 1912: RETURN_LONG(bytes);
! 1913: }
! 1914: }
! 1915: }
! 1916: /* }}} */
! 1917:
! 1918: /* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
! 1919: Canonicalize nodes to a string */
! 1920: PHP_METHOD(domnode, C14N)
! 1921: {
! 1922: dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
! 1923: }
! 1924: /* }}} */
! 1925:
! 1926: /* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
! 1927: Canonicalize nodes to a file */
! 1928: PHP_METHOD(domnode, C14NFile)
! 1929: {
! 1930: dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
! 1931: }
! 1932: /* }}} */
! 1933:
! 1934: /* {{{ proto int DOMNode::getNodePath()
! 1935: Gets an xpath for a node */
! 1936: PHP_METHOD(domnode, getNodePath)
! 1937: {
! 1938: zval *id;
! 1939: xmlNode *nodep;
! 1940: dom_object *intern;
! 1941: char *value;
! 1942:
! 1943: DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
! 1944:
! 1945: value = xmlGetNodePath(nodep);
! 1946: if (value == NULL) {
! 1947: RETURN_NULL();
! 1948: } else {
! 1949: RETVAL_STRING(value, 1);
! 1950: xmlFree(value);
! 1951: }
! 1952: }
! 1953: /* }}} */
! 1954:
! 1955: /* {{{ proto int DOMNode::getLineNo()
! 1956: Gets line number for a node */
! 1957: PHP_METHOD(domnode, getLineNo)
! 1958: {
! 1959: zval *id;
! 1960: xmlNode *nodep;
! 1961: dom_object *intern;
! 1962:
! 1963: if (zend_parse_parameters_none() == FAILURE) {
! 1964: return;
! 1965: }
! 1966:
! 1967: DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
! 1968:
! 1969: RETURN_LONG(xmlGetLineNo(nodep));
! 1970: }
! 1971: /* }}} */
! 1972:
! 1973: #endif
! 1974:
! 1975: /*
! 1976: * Local variables:
! 1977: * tab-width: 4
! 1978: * c-basic-offset: 4
! 1979: * End:
! 1980: * vim600: noet sw=4 ts=4 fdm=marker
! 1981: * vim<600: noet sw=4 ts=4
! 1982: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>