Back to index

php5  5.3.10
node.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Christian Stocker <chregu@php.net>                          |
00016    |          Rob Richards <rrichards@php.net>                            |
00017    +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: node.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025 
00026 #include "php.h"
00027 #if HAVE_LIBXML && HAVE_DOM
00028 #include "php_dom.h"
00029 
00030 /* {{{ arginfo */
00031 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1)
00032        ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
00033        ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1)
00034 ZEND_END_ARG_INFO();
00035 
00036 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2)
00037        ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
00038        ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
00039 ZEND_END_ARG_INFO();
00040 
00041 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1)
00042        ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
00043 ZEND_END_ARG_INFO();
00044 
00045 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1)
00046        ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
00047 ZEND_END_ARG_INFO();
00048 
00049 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0)
00050 ZEND_END_ARG_INFO();
00051 
00052 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1)
00053        ZEND_ARG_INFO(0, deep)
00054 ZEND_END_ARG_INFO();
00055 
00056 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0)
00057 ZEND_END_ARG_INFO();
00058 
00059 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2)
00060        ZEND_ARG_INFO(0, feature)
00061        ZEND_ARG_INFO(0, version)
00062 ZEND_END_ARG_INFO();
00063 
00064 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0)
00065 ZEND_END_ARG_INFO();
00066 
00067 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1)
00068        ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
00069 ZEND_END_ARG_INFO();
00070 
00071 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1)
00072        ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
00073 ZEND_END_ARG_INFO();
00074 
00075 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1)
00076        ZEND_ARG_INFO(0, namespaceURI)
00077 ZEND_END_ARG_INFO();
00078 
00079 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1)
00080        ZEND_ARG_INFO(0, namespaceURI)
00081 ZEND_END_ARG_INFO();
00082 
00083 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1)
00084        ZEND_ARG_INFO(0, prefix)
00085 ZEND_END_ARG_INFO();
00086 
00087 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1)
00088        ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
00089 ZEND_END_ARG_INFO();
00090 
00091 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2)
00092        ZEND_ARG_INFO(0, feature)
00093        ZEND_ARG_INFO(0, version)
00094 ZEND_END_ARG_INFO();
00095 
00096 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3)
00097        ZEND_ARG_INFO(0, key)
00098        ZEND_ARG_INFO(0, data)
00099        ZEND_ARG_INFO(0, handler)
00100 ZEND_END_ARG_INFO();
00101 
00102 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1)
00103        ZEND_ARG_INFO(0, key)
00104 ZEND_END_ARG_INFO();
00105 
00106 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0)
00107 ZEND_END_ARG_INFO();
00108 
00109 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getLineNo, 0, 0, 0)
00110 ZEND_END_ARG_INFO();
00111 
00112 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0)
00113        ZEND_ARG_INFO(0, exclusive)
00114        ZEND_ARG_INFO(0, with_comments)
00115        ZEND_ARG_ARRAY_INFO(0, xpath, 1)
00116        ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
00117 ZEND_END_ARG_INFO();
00118 
00119 ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1)
00120        ZEND_ARG_INFO(0, uri)
00121        ZEND_ARG_INFO(0, exclusive)
00122        ZEND_ARG_INFO(0, with_comments)
00123        ZEND_ARG_ARRAY_INFO(0, xpath, 1)
00124        ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
00125 ZEND_END_ARG_INFO();
00126 /* }}} */
00127 
00128 /*
00129 * class DOMNode 
00130 *
00131 * URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247
00132 * Since: 
00133 */
00134 
00135 const zend_function_entry php_dom_node_class_functions[] = { /* {{{ */
00136        PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before)
00137        PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child)
00138        PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child)
00139        PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child)
00140        PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes)
00141        PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node)
00142        PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize)
00143        PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported)
00144        PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes)
00145        PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position)
00146        PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node)
00147        PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix)
00148        PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace)
00149        PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri)
00150        PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node)
00151        PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature)
00152        PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data)
00153        PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data)
00154        PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC)
00155        PHP_ME(domnode, getLineNo, arginfo_dom_node_getLineNo, ZEND_ACC_PUBLIC)
00156        PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC)
00157        PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC)
00158        PHP_FE_END
00159 };
00160 /* }}} */
00161 
00162 static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
00163 {
00164        xmlNsPtr nsptr, nsdftptr, curns, prevns = NULL;
00165 
00166        if (nodep->type == XML_ELEMENT_NODE) {
00167               /* Following if block primarily used for inserting nodes created via createElementNS */
00168               if (nodep->nsDef != NULL) {
00169                      curns = nodep->nsDef;
00170                      while (curns) {
00171                             nsdftptr = curns->next;
00172                             if (curns->href != NULL) {
00173                                    if((nsptr = xmlSearchNsByHref(doc, nodep->parent, curns->href)) && 
00174                                           (curns->prefix == NULL || xmlStrEqual(nsptr->prefix, curns->prefix))) {
00175                                           curns->next = NULL;
00176                                           if (prevns == NULL) {
00177                                                  nodep->nsDef = nsdftptr;
00178                                           } else {
00179                                                  prevns->next = nsdftptr;
00180                                           }
00181                                           dom_set_old_ns(doc, curns);
00182                                           curns = prevns;
00183                                    }
00184                             }
00185                             prevns = curns;
00186                             curns = nsdftptr;
00187                      }
00188               }
00189               xmlReconciliateNs(doc, nodep);
00190        }
00191 }
00192 /* }}} */
00193 
00194 /* {{{ nodeName      string 
00195 readonly=yes 
00196 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
00197 Since: 
00198 */
00199 int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
00200 {
00201        xmlNode *nodep;
00202        xmlNsPtr ns;
00203        char *str = NULL;
00204        xmlChar *qname = NULL;
00205 
00206        nodep = dom_object_get_node(obj);
00207 
00208        if (nodep == NULL) {
00209               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00210               return FAILURE;
00211        }
00212 
00213        switch (nodep->type) {
00214               case XML_ATTRIBUTE_NODE:
00215               case XML_ELEMENT_NODE:
00216                      ns = nodep->ns;
00217                      if (ns != NULL && ns->prefix) {
00218                             qname = xmlStrdup(ns->prefix);
00219                             qname = xmlStrcat(qname, ":");
00220                             qname = xmlStrcat(qname, nodep->name);
00221                             str = qname;
00222                      } else {
00223                             str = (char *) nodep->name;
00224                      }
00225                      break;
00226               case XML_NAMESPACE_DECL:
00227                      ns = nodep->ns;
00228                      if (ns != NULL && ns->prefix) {
00229                             qname = xmlStrdup("xmlns");
00230                             qname = xmlStrcat(qname, ":");
00231                             qname = xmlStrcat(qname, nodep->name);
00232                             str = qname;
00233                      } else {
00234                             str = (char *) nodep->name;
00235                      }
00236                      break;
00237               case XML_DOCUMENT_TYPE_NODE:
00238               case XML_DTD_NODE:
00239               case XML_PI_NODE:
00240               case XML_ENTITY_DECL:
00241               case XML_ENTITY_REF_NODE:
00242               case XML_NOTATION_NODE:
00243                      str = (char *) nodep->name;
00244                      break;
00245               case XML_CDATA_SECTION_NODE:
00246                      str = "#cdata-section";
00247                      break;
00248               case XML_COMMENT_NODE:
00249                      str = "#comment";
00250                      break;
00251               case XML_HTML_DOCUMENT_NODE:
00252               case XML_DOCUMENT_NODE:
00253                      str = "#document";
00254                      break;
00255               case XML_DOCUMENT_FRAG_NODE:
00256                      str = "#document-fragment";
00257                      break;
00258               case XML_TEXT_NODE:
00259                      str = "#text";
00260                      break;
00261               default:
00262                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type");
00263        }
00264 
00265        ALLOC_ZVAL(*retval);
00266 
00267        if(str != NULL) {
00268               ZVAL_STRING(*retval, str, 1);
00269        } else {
00270               ZVAL_EMPTY_STRING(*retval);
00271        }
00272        
00273        if (qname != NULL) {
00274               xmlFree(qname);
00275        }
00276 
00277        return SUCCESS;
00278 
00279 }
00280 
00281 /* }}} */
00282 
00283 /* {{{ nodeValue     string 
00284 readonly=no 
00285 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
00286 Since: 
00287 */
00288 int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC)
00289 {
00290        xmlNode *nodep;
00291        char *str = NULL;
00292 
00293        nodep = dom_object_get_node(obj);
00294 
00295        if (nodep == NULL) {
00296               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00297               return FAILURE;
00298        }
00299 
00300        /* Access to Element node is implemented as a convience method */
00301        switch (nodep->type) {
00302               case XML_ATTRIBUTE_NODE:
00303               case XML_TEXT_NODE:
00304               case XML_ELEMENT_NODE:
00305               case XML_COMMENT_NODE:
00306               case XML_CDATA_SECTION_NODE:
00307               case XML_PI_NODE:
00308                      str = xmlNodeGetContent(nodep);
00309                      break;
00310               case XML_NAMESPACE_DECL:
00311                      str = xmlNodeGetContent(nodep->children);
00312                      break;
00313               default:
00314                      str = NULL;
00315                      break;
00316        }
00317 
00318        ALLOC_ZVAL(*retval);
00319 
00320        if(str != NULL) {
00321               ZVAL_STRING(*retval, str, 1);
00322               xmlFree(str);
00323        } else {
00324               ZVAL_NULL(*retval);
00325        }
00326 
00327 
00328        return SUCCESS;
00329 
00330 }
00331 
00332 int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
00333 {
00334        xmlNode *nodep;
00335        zval value_copy;
00336 
00337        nodep = dom_object_get_node(obj);
00338 
00339        if (nodep == NULL) {
00340               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00341               return FAILURE;
00342        }
00343 
00344        /* Access to Element node is implemented as a convience method */
00345        switch (nodep->type) {
00346               case XML_ELEMENT_NODE:
00347               case XML_ATTRIBUTE_NODE:
00348                      if (nodep->children) {
00349                             node_list_unlink(nodep->children TSRMLS_CC);
00350                      }
00351               case XML_TEXT_NODE:
00352               case XML_COMMENT_NODE:
00353               case XML_CDATA_SECTION_NODE:
00354               case XML_PI_NODE:
00355                      if (newval->type != IS_STRING) {
00356                             if(Z_REFCOUNT_P(newval) > 1) {
00357                                    value_copy = *newval;
00358                                    zval_copy_ctor(&value_copy);
00359                                    newval = &value_copy;
00360                             }
00361                             convert_to_string(newval);
00362                      }
00363                      xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
00364                      if (newval == &value_copy) {
00365                             zval_dtor(newval);
00366                      }
00367                      break;
00368               default:
00369                      break;
00370        }
00371 
00372        return SUCCESS;
00373 }
00374 
00375 /* }}} */
00376 
00377 /* {{{ nodeType      int
00378 readonly=yes 
00379 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558
00380 Since:
00381 */
00382 int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC)
00383 {
00384        xmlNode *nodep;
00385 
00386        nodep = dom_object_get_node(obj);
00387 
00388        if (nodep == NULL) {
00389               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00390               return FAILURE;
00391        }
00392 
00393        ALLOC_ZVAL(*retval);
00394 
00395        /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */
00396        if (nodep->type == XML_DTD_NODE) {
00397               ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE);
00398        } else {
00399               ZVAL_LONG(*retval, nodep->type);
00400        }
00401 
00402        return SUCCESS;
00403 }
00404 
00405 /* }}} */
00406 
00407 /* {{{ parentNode    DomNode       
00408 readonly=yes 
00409 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317
00410 Since: 
00411 */
00412 int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
00413 {
00414        xmlNode *nodep, *nodeparent;
00415        int ret;
00416 
00417        nodep = dom_object_get_node(obj);
00418 
00419        if (nodep == NULL) {
00420               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00421               return FAILURE;
00422        }
00423 
00424        ALLOC_ZVAL(*retval);
00425 
00426        nodeparent = nodep->parent;
00427        if (!nodeparent) {
00428               ZVAL_NULL(*retval);
00429               return SUCCESS;
00430        }
00431 
00432        if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, NULL, *retval, obj TSRMLS_CC))) {
00433               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
00434               return FAILURE;
00435        }
00436        return SUCCESS;
00437 }
00438 
00439 /* }}} */
00440 
00441 /* {{{ childNodes    DomNodeList   
00442 readonly=yes 
00443 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987
00444 Since: 
00445 */
00446 int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
00447 {
00448        xmlNode *nodep;
00449        dom_object *intern;
00450 
00451        nodep = dom_object_get_node(obj);
00452 
00453        if (nodep == NULL) {
00454               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00455               return FAILURE;
00456        }
00457 
00458        ALLOC_ZVAL(*retval);
00459        
00460        if (dom_node_children_valid(nodep) == FAILURE) {
00461               ZVAL_NULL(*retval);
00462        } else {
00463               php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
00464               intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
00465               dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
00466        }
00467 
00468        return SUCCESS;
00469 }
00470 
00471 /* }}} */
00472 
00473 /* {{{ firstChild DomNode   
00474 readonly=yes 
00475 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388
00476 Since: 
00477 */
00478 int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
00479 {
00480        xmlNode *nodep, *first = NULL;
00481        int ret;
00482 
00483        nodep = dom_object_get_node(obj);
00484 
00485        if (nodep == NULL) {
00486               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00487               return FAILURE;
00488        }
00489 
00490        if (dom_node_children_valid(nodep) == SUCCESS) {
00491               first = nodep->children;
00492        }
00493 
00494        ALLOC_ZVAL(*retval);
00495 
00496        if (!first) {
00497               ZVAL_NULL(*retval);
00498               return SUCCESS;
00499        }
00500 
00501        if (NULL == (*retval = php_dom_create_object(first, &ret, NULL, *retval, obj TSRMLS_CC))) {
00502               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
00503               return FAILURE;
00504        }
00505        return SUCCESS;
00506 }
00507 
00508 /* }}} */
00509 
00510 /* {{{ lastChild     DomNode       
00511 readonly=yes 
00512 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB
00513 Since: 
00514 */
00515 int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
00516 {
00517        xmlNode *nodep, *last = NULL;
00518        int ret;
00519 
00520        nodep = dom_object_get_node(obj);
00521 
00522        if (nodep == NULL) {
00523               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00524               return FAILURE;
00525        }
00526 
00527        if (dom_node_children_valid(nodep) == SUCCESS) {
00528               last = nodep->last;
00529        }
00530 
00531        ALLOC_ZVAL(*retval);
00532 
00533        if (!last) {
00534               ZVAL_NULL(*retval);
00535               return SUCCESS;
00536        }
00537 
00538        if (NULL == (*retval = php_dom_create_object(last, &ret, NULL, *retval, obj TSRMLS_CC))) {
00539               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
00540               return FAILURE;
00541        }
00542        return SUCCESS;
00543 }
00544 
00545 /* }}} */
00546 
00547 /* {{{ previousSibling      DomNode       
00548 readonly=yes 
00549 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8
00550 Since: 
00551 */
00552 int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
00553 {
00554        xmlNode *nodep, *prevsib;
00555        int ret;
00556 
00557        nodep = dom_object_get_node(obj);
00558 
00559        if (nodep == NULL) {
00560               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00561               return FAILURE;
00562        }
00563 
00564        ALLOC_ZVAL(*retval);
00565 
00566        prevsib = nodep->prev;
00567        if (!prevsib) {
00568               ZVAL_NULL(*retval);
00569               return SUCCESS;
00570        }
00571 
00572        if (NULL == (*retval = php_dom_create_object(prevsib, &ret, NULL, *retval, obj TSRMLS_CC))) {
00573               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
00574               return FAILURE;
00575        }
00576        return SUCCESS;
00577 }
00578 
00579 /* }}} */
00580 
00581 /* {{{ nextSibling   DomNode
00582 readonly=yes 
00583 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F
00584 Since:
00585 */
00586 int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
00587 {
00588        xmlNode *nodep, *nextsib;
00589        int ret;
00590 
00591        nodep = dom_object_get_node(obj);
00592 
00593        if (nodep == NULL) {
00594               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00595               return FAILURE;
00596        }
00597 
00598        nextsib = nodep->next;
00599        if (!nextsib) {
00600               return FAILURE;
00601        }
00602 
00603        ALLOC_ZVAL(*retval);
00604 
00605        if (NULL == (*retval = php_dom_create_object(nextsib, &ret, NULL, *retval, obj TSRMLS_CC))) {
00606               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
00607               return FAILURE;
00608        }
00609        return SUCCESS;
00610 }
00611 
00612 /* }}} */
00613 
00614 /* {{{ attributes    DomNamedNodeMap      
00615 readonly=yes 
00616 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096
00617 Since: 
00618 */
00619 int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
00620 {
00621        xmlNode *nodep;
00622        dom_object *intern;
00623 
00624        nodep = dom_object_get_node(obj);
00625 
00626        if (nodep == NULL) {
00627               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00628               return FAILURE;
00629        }
00630 
00631        ALLOC_ZVAL(*retval);
00632 
00633        if (nodep->type == XML_ELEMENT_NODE) {
00634               php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
00635               intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
00636               dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
00637        } else {
00638               ZVAL_NULL(*retval);
00639        }
00640 
00641        return SUCCESS;
00642 }
00643 
00644 /* }}} */
00645 
00646 /* {{{ ownerDocument DomDocument   
00647 readonly=yes 
00648 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc
00649 Since: 
00650 */
00651 int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC)
00652 {
00653        xmlNode *nodep;
00654        xmlDocPtr docp;
00655        int ret;
00656 
00657        nodep = dom_object_get_node(obj);
00658 
00659        if (nodep == NULL) {
00660               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00661               return FAILURE;
00662        }
00663 
00664        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
00665               ALLOC_ZVAL(*retval);
00666               ZVAL_NULL(*retval);
00667               return SUCCESS;
00668        }
00669 
00670        docp = nodep->doc;
00671        if (!docp) {
00672               return FAILURE;
00673        }
00674 
00675        ALLOC_ZVAL(*retval);
00676 
00677        if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, NULL, *retval, obj TSRMLS_CC))) {
00678               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
00679               return FAILURE;
00680        }
00681        return SUCCESS;
00682 }
00683 
00684 /* }}} */
00685 
00686 /* {{{ namespaceUri  string 
00687 readonly=yes 
00688 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname
00689 Since: DOM Level 2
00690 */
00691 int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
00692 {
00693        xmlNode *nodep;
00694        char *str = NULL;
00695 
00696        nodep = dom_object_get_node(obj);
00697 
00698        if (nodep == NULL) {
00699               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00700               return FAILURE;
00701        }
00702 
00703        switch (nodep->type) {
00704               case XML_ELEMENT_NODE:
00705               case XML_ATTRIBUTE_NODE:
00706               case XML_NAMESPACE_DECL:
00707                      if (nodep->ns != NULL) {
00708                             str = (char *) nodep->ns->href;
00709                      }
00710                      break;
00711               default:
00712                      str = NULL;
00713                      break;
00714        }
00715 
00716        ALLOC_ZVAL(*retval);
00717 
00718        if(str != NULL) {
00719               ZVAL_STRING(*retval, str, 1);
00720        } else {
00721               ZVAL_NULL(*retval);
00722        }
00723 
00724        return SUCCESS;
00725 }
00726 
00727 /* }}} */
00728 
00729 /* {{{ prefix string 
00730 readonly=no 
00731 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
00732 Since: DOM Level 2
00733 */
00734 int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC)
00735 {
00736        xmlNode *nodep;
00737        xmlNsPtr ns;
00738        char *str = NULL;
00739 
00740        nodep = dom_object_get_node(obj);
00741 
00742        if (nodep == NULL) {
00743               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00744               return FAILURE;
00745        }
00746 
00747        switch (nodep->type) {
00748               case XML_ELEMENT_NODE:
00749               case XML_ATTRIBUTE_NODE:
00750               case XML_NAMESPACE_DECL:
00751                      ns = nodep->ns;
00752                      if (ns != NULL && ns->prefix) {
00753                             str = (char *) ns->prefix;
00754                      }
00755                      break;
00756               default:
00757                      str = NULL;
00758                      break;
00759        }
00760 
00761        ALLOC_ZVAL(*retval);
00762 
00763        if (str == NULL) {
00764               ZVAL_EMPTY_STRING(*retval);
00765        } else {
00766               ZVAL_STRING(*retval, str, 1);
00767        }
00768        return SUCCESS;
00769 
00770 }
00771 
00772 int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
00773 {
00774        zval value_copy;
00775        xmlNode *nodep, *nsnode = NULL;
00776        xmlNsPtr ns = NULL, curns;
00777        char *strURI;
00778        char *prefix;
00779 
00780        nodep = dom_object_get_node(obj);
00781 
00782        if (nodep == NULL) {
00783               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00784               return FAILURE;
00785        }
00786 
00787        switch (nodep->type) {
00788               case XML_ELEMENT_NODE:
00789                      nsnode = nodep;
00790               case XML_ATTRIBUTE_NODE:
00791                      if (nsnode == NULL) {
00792                             nsnode = nodep->parent;
00793                             if (nsnode == NULL) {
00794                                    nsnode = xmlDocGetRootElement(nodep->doc);
00795                             }
00796                      }
00797                      if (newval->type != IS_STRING) {
00798                             if(Z_REFCOUNT_P(newval) > 1) {
00799                                    value_copy = *newval;
00800                                    zval_copy_ctor(&value_copy);
00801                                    newval = &value_copy;
00802                             }
00803                             convert_to_string(newval);
00804                      }
00805                      prefix = Z_STRVAL_P(newval);
00806                      if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
00807                             strURI = (char *) nodep->ns->href;
00808                             if (strURI == NULL || 
00809                                    (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
00810                                    (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
00811                                     strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
00812                                    (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
00813                                    ns = NULL;
00814                             } else {
00815                                    curns = nsnode->nsDef;
00816                                    while (curns != NULL) {
00817                                           if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) {
00818                                                  ns = curns;
00819                                                  break;
00820                                           }
00821                                           curns = curns->next;
00822                                    }
00823                                    if (ns == NULL) {
00824                                           ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix);
00825                                    }
00826                             }
00827 
00828                             if (ns == NULL) {
00829                                    if (newval == &value_copy) {
00830                                           zval_dtor(newval);
00831                                    }
00832                                    php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC);
00833                                    return FAILURE;
00834                             }
00835 
00836                             xmlSetNs(nodep, ns);
00837                      }
00838                      if (newval == &value_copy) {
00839                             zval_dtor(newval);
00840                      }
00841                      break;
00842               default:
00843                      break;
00844        }
00845 
00846        return SUCCESS;
00847 }
00848 
00849 /* }}} */
00850 
00851 /* {{{ localName     string 
00852 readonly=yes 
00853 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN
00854 Since: DOM Level 2
00855 */
00856 int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC)
00857 {
00858        xmlNode *nodep;
00859 
00860        nodep = dom_object_get_node(obj);
00861 
00862        if (nodep == NULL) {
00863               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00864               return FAILURE;
00865        }
00866 
00867        ALLOC_ZVAL(*retval);
00868 
00869        if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) {
00870               ZVAL_STRING(*retval, (char *) (nodep->name), 1);
00871        } else {
00872               ZVAL_NULL(*retval);
00873        }
00874 
00875        return SUCCESS;
00876 }
00877 
00878 /* }}} */
00879 
00880 /* {{{ baseURI       string
00881 readonly=yes
00882 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI
00883 Since: DOM Level 3
00884 */
00885 int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
00886 {
00887        xmlNode *nodep;
00888        xmlChar *baseuri;
00889 
00890        nodep = dom_object_get_node(obj);
00891 
00892        if (nodep == NULL) {
00893               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00894               return FAILURE;
00895        }
00896 
00897        ALLOC_ZVAL(*retval);
00898 
00899        baseuri = xmlNodeGetBase(nodep->doc, nodep);
00900        if (baseuri) {
00901               ZVAL_STRING(*retval, (char *) (baseuri), 1);
00902               xmlFree(baseuri);
00903        } else {
00904               ZVAL_NULL(*retval);
00905        }
00906 
00907        return SUCCESS;
00908 }
00909 
00910 /* }}} */
00911 
00912 /* {{{ textContent   string 
00913 readonly=no 
00914 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
00915 Since: DOM Level 3
00916 */
00917 int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
00918 {
00919        xmlNode *nodep;
00920        char *str = NULL;
00921 
00922        nodep = dom_object_get_node(obj);
00923 
00924        if (nodep == NULL) {
00925               php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
00926               return FAILURE;
00927        }
00928 
00929        str = xmlNodeGetContent(nodep);
00930 
00931        ALLOC_ZVAL(*retval);
00932 
00933        if(str != NULL) {
00934               ZVAL_STRING(*retval, str, 1);
00935               xmlFree(str);
00936        } else {
00937               ZVAL_EMPTY_STRING(*retval);
00938        }
00939 
00940        return SUCCESS;
00941 }
00942 
00943 int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
00944 {
00945        return SUCCESS;
00946 }
00947 
00948 /* }}} */
00949 
00950 static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlNodePtr nextsib, xmlNodePtr fragment, dom_object *intern, dom_object *childobj TSRMLS_DC) /* {{{ */
00951 {
00952        xmlNodePtr newchild, node;
00953 
00954        newchild = fragment->children;
00955 
00956        if (newchild) {
00957               if (prevsib == NULL) {
00958                      nodep->children = newchild;
00959               } else {
00960                      prevsib->next = newchild;
00961               }
00962               newchild->prev = prevsib;
00963               if (nextsib == NULL) {
00964                      nodep->last = fragment->last;
00965               } else {
00966                      fragment->last->next = nextsib;
00967                      nextsib->prev = fragment->last;
00968               }
00969 
00970               node = newchild;
00971               while (node != NULL) {
00972                      node->parent = nodep;
00973                      if (node->doc != nodep->doc) {
00974                             xmlSetTreeDoc(node, nodep->doc);
00975                             if (node->_private != NULL) {
00976                                    childobj = node->_private;
00977                                    childobj->document = intern->document;
00978                                    php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
00979                             }
00980                      }
00981                      if (node == fragment->last) {
00982                             break;
00983                      }
00984                      node = node->next;
00985               }
00986 
00987               fragment->children = NULL;
00988               fragment->last = NULL;
00989        }
00990 
00991        return newchild;
00992 }
00993 /* }}} */
00994 
00995 /* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild);
00996 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
00997 Since:
00998 */
00999 PHP_FUNCTION(dom_node_insert_before)
01000 {
01001        zval *id, *node, *ref = NULL;
01002        xmlNodePtr child, new_child, parentp, refp;
01003        dom_object *intern, *childobj, *refpobj;
01004        int ret, stricterror;
01005 
01006        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) {
01007               return;
01008        }
01009 
01010        DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
01011 
01012        if (dom_node_children_valid(parentp) == FAILURE) {
01013               RETURN_FALSE;
01014        }
01015 
01016        DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
01017 
01018        new_child = NULL;
01019 
01020        stricterror = dom_get_strict_error(intern->document);
01021 
01022        if (dom_node_is_read_only(parentp) == SUCCESS ||
01023               (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
01024               php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
01025               RETURN_FALSE;
01026        }
01027 
01028        if (dom_hierarchy(parentp, child) == FAILURE) {
01029               php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
01030               RETURN_FALSE;
01031        }
01032 
01033        if (child->doc != parentp->doc && child->doc != NULL) {
01034               php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
01035               RETURN_FALSE;
01036        }
01037 
01038        if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
01039               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
01040               RETURN_FALSE;
01041        }
01042 
01043        if (child->doc == NULL && parentp->doc != NULL) {
01044               childobj->document = intern->document;
01045               php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
01046        }
01047 
01048        if (ref != NULL) {
01049               DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
01050               if (refp->parent != parentp) {
01051                      php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
01052                      RETURN_FALSE;
01053               }
01054 
01055               if (child->parent != NULL) {
01056                      xmlUnlinkNode(child);
01057               }
01058 
01059               if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE || 
01060                      (refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) {
01061                      if (child->doc == NULL) {
01062                             xmlSetTreeDoc(child, parentp->doc);
01063                      }
01064                      new_child = child;
01065                      new_child->parent = refp->parent;
01066                      new_child->next = refp;
01067                      new_child->prev = refp->prev;
01068                      refp->prev = new_child;
01069                      if (new_child->prev != NULL) {
01070                             new_child->prev->next = new_child;
01071                      }
01072                      if (new_child->parent != NULL) {
01073                             if (new_child->parent->children == refp) {
01074                                    new_child->parent->children = new_child;
01075                             }
01076                      }
01077 
01078               } else if (child->type == XML_ATTRIBUTE_NODE) {
01079                      xmlAttrPtr lastattr;
01080 
01081                      if (child->ns == NULL)
01082                             lastattr = xmlHasProp(refp->parent, child->name);
01083                      else
01084                             lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
01085                      if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
01086                             if (lastattr != (xmlAttrPtr) child) {
01087                                    xmlUnlinkNode((xmlNodePtr) lastattr);
01088                                    php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
01089                             } else {
01090                                    DOM_RET_OBJ_EX(child, &ret, intern);
01091                                    return;
01092                             }
01093                      }
01094               } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
01095                      new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC);
01096               }
01097 
01098               if (new_child == NULL) {
01099                      new_child = xmlAddPrevSibling(refp, child);
01100               }
01101        } else {
01102               if (child->parent != NULL){
01103                      xmlUnlinkNode(child);
01104               }
01105               if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) {
01106                      child->parent = parentp;
01107                      if (child->doc == NULL) {
01108                             xmlSetTreeDoc(child, parentp->doc);
01109                      }
01110                      new_child = child;
01111                      if (parentp->children == NULL) {
01112                             parentp->children = child;
01113                             parentp->last = child;
01114                      } else {
01115                             child = parentp->last;
01116                             child->next = new_child;
01117                             new_child->prev = child;
01118                             parentp->last = new_child;
01119                      }
01120               } else        if (child->type == XML_ATTRIBUTE_NODE) {
01121                      xmlAttrPtr lastattr;
01122 
01123                      if (child->ns == NULL)
01124                             lastattr = xmlHasProp(parentp, child->name);
01125                      else
01126                             lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
01127                      if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
01128                             if (lastattr != (xmlAttrPtr) child) {
01129                                    xmlUnlinkNode((xmlNodePtr) lastattr);
01130                                    php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
01131                             } else {
01132                                    DOM_RET_OBJ_EX(child, &ret, intern);
01133                                    return;
01134                             }
01135                      }
01136               } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
01137                      new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC);
01138               }
01139               if (new_child == NULL) {
01140                      new_child = xmlAddChild(parentp, child);
01141               }
01142        }
01143 
01144        if (NULL == new_child) {
01145               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode");
01146               RETURN_FALSE;
01147        }
01148 
01149        dom_reconcile_ns(parentp->doc, new_child);
01150 
01151        DOM_RET_OBJ_EX(new_child, &ret, intern);
01152 
01153 }
01154 /* }}} end dom_node_insert_before */
01155 
01156 /* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);
01157 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
01158 Since: 
01159 */
01160 PHP_FUNCTION(dom_node_replace_child)
01161 {
01162        zval *id, *newnode, *oldnode;
01163        xmlNodePtr children, newchild, oldchild, nodep;
01164        dom_object *intern, *newchildobj, *oldchildobj;
01165        int foundoldchild = 0, stricterror;
01166 
01167        int ret;
01168 
01169        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) {
01170               return;
01171        }
01172 
01173        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01174 
01175        if (dom_node_children_valid(nodep) == FAILURE) {
01176               RETURN_FALSE;
01177        }
01178 
01179        DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
01180        DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
01181 
01182        children = nodep->children;
01183        if (!children) {
01184               RETURN_FALSE;
01185        }
01186 
01187        stricterror = dom_get_strict_error(intern->document);
01188 
01189        if (dom_node_is_read_only(nodep) == SUCCESS || 
01190               (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
01191               php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
01192               RETURN_FALSE;
01193        }
01194 
01195        if (newchild->doc != nodep->doc && newchild->doc != NULL) {
01196               php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
01197               RETURN_FALSE;
01198        }
01199 
01200        if (dom_hierarchy(nodep, newchild) == FAILURE) {
01201               php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
01202               RETURN_FALSE;
01203        }
01204 
01205        /* check for the old child and whether the new child is already a child */
01206        while (children) {
01207               if (children == oldchild) {
01208                      foundoldchild = 1;
01209                      break;
01210               }
01211               children = children->next;
01212        }
01213 
01214        if (foundoldchild) {
01215               if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
01216                      xmlNodePtr prevsib, nextsib;
01217                      prevsib = oldchild->prev;
01218                      nextsib = oldchild->next;
01219 
01220                      xmlUnlinkNode(oldchild);
01221 
01222                      newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC);
01223                      if (newchild) {
01224                             dom_reconcile_ns(nodep->doc, newchild);
01225                      }
01226               } else if (oldchild != newchild) {
01227                      if (newchild->doc == NULL && nodep->doc != NULL) {
01228                             xmlSetTreeDoc(newchild, nodep->doc);
01229                             newchildobj->document = intern->document;
01230                             php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
01231                      }
01232                      xmlReplaceNode(oldchild, newchild);
01233                      dom_reconcile_ns(nodep->doc, newchild);
01234               }
01235               DOM_RET_OBJ_EX(oldchild, &ret, intern);
01236               return;
01237        } else {
01238               php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
01239               RETURN_FALSE;
01240        }
01241 }
01242 /* }}} end dom_node_replace_child */
01243 
01244 /* {{{ proto DomNode dom_node_remove_child(DomNode oldChild);
01245 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
01246 Since: 
01247 */
01248 PHP_FUNCTION(dom_node_remove_child)
01249 {
01250        zval *id, *node;
01251        xmlNodePtr children, child, nodep;
01252        dom_object *intern, *childobj;
01253        int ret, stricterror;
01254 
01255        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
01256               return;
01257        }
01258 
01259        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01260 
01261        if (dom_node_children_valid(nodep) == FAILURE) {
01262               RETURN_FALSE;
01263        }
01264 
01265        DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
01266 
01267        stricterror = dom_get_strict_error(intern->document);
01268 
01269        if (dom_node_is_read_only(nodep) == SUCCESS || 
01270               (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
01271               php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
01272               RETURN_FALSE;
01273        }
01274 
01275        children = nodep->children;
01276        if (!children) {
01277               php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
01278               RETURN_FALSE;
01279        }
01280 
01281        while (children) {
01282               if (children == child) {
01283                      xmlUnlinkNode(child);
01284                      DOM_RET_OBJ_EX(child, &ret, intern);
01285                      return;
01286               }
01287               children = children->next;
01288        }
01289 
01290        php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
01291        RETURN_FALSE
01292 }
01293 /* }}} end dom_node_remove_child */
01294 
01295 /* {{{ proto DomNode dom_node_append_child(DomNode newChild);
01296 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
01297 Since: 
01298 */
01299 PHP_FUNCTION(dom_node_append_child)
01300 {
01301        zval *id, *node;
01302        xmlNodePtr child, nodep, new_child = NULL;
01303        dom_object *intern, *childobj;
01304        int ret, stricterror;
01305 
01306        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
01307               return;
01308        }
01309 
01310        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01311 
01312        if (dom_node_children_valid(nodep) == FAILURE) {
01313               RETURN_FALSE;
01314        }
01315 
01316        DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
01317 
01318        stricterror = dom_get_strict_error(intern->document);
01319 
01320        if (dom_node_is_read_only(nodep) == SUCCESS ||
01321               (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
01322               php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
01323               RETURN_FALSE;
01324        }
01325 
01326        if (dom_hierarchy(nodep, child) == FAILURE) {
01327               php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
01328               RETURN_FALSE;
01329        }
01330 
01331        if (!(child->doc == NULL || child->doc == nodep->doc)) {
01332               php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
01333               RETURN_FALSE;
01334        }
01335 
01336        if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
01337               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
01338               RETURN_FALSE;
01339        }
01340 
01341        if (child->doc == NULL && nodep->doc != NULL) {
01342               childobj->document = intern->document;
01343               php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
01344        }
01345 
01346        if (child->parent != NULL){
01347               xmlUnlinkNode(child);
01348        }
01349 
01350        if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) {
01351               child->parent = nodep;
01352               if (child->doc == NULL) {
01353                      xmlSetTreeDoc(child, nodep->doc);
01354               }
01355               new_child = child;
01356               if (nodep->children == NULL) {
01357                      nodep->children = child;
01358                      nodep->last = child;
01359               } else {
01360                      child = nodep->last;
01361                      child->next = new_child;
01362                      new_child->prev = child;
01363                      nodep->last = new_child;
01364               }
01365        } else        if (child->type == XML_ATTRIBUTE_NODE) {
01366               xmlAttrPtr lastattr;
01367 
01368               if (child->ns == NULL)
01369                      lastattr = xmlHasProp(nodep, child->name);
01370               else
01371                      lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
01372               if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
01373                      if (lastattr != (xmlAttrPtr) child) {
01374                             xmlUnlinkNode((xmlNodePtr) lastattr);
01375                             php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
01376                      }
01377               }
01378        } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
01379               new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC);
01380        }
01381 
01382        if (new_child == NULL) {
01383               new_child = xmlAddChild(nodep, child);
01384               if (new_child == NULL) {
01385                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node");
01386                      RETURN_FALSE;
01387               }
01388        }
01389 
01390        dom_reconcile_ns(nodep->doc, new_child);
01391 
01392        DOM_RET_OBJ_EX(new_child, &ret, intern);
01393 }
01394 /* }}} end dom_node_append_child */
01395 
01396 /* {{{ proto boolean dom_node_has_child_nodes();
01397 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
01398 Since: 
01399 */
01400 PHP_FUNCTION(dom_node_has_child_nodes)
01401 {
01402        zval *id;
01403        xmlNode *nodep;
01404        dom_object *intern;
01405 
01406        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
01407               return;
01408        }
01409 
01410        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01411 
01412        if (dom_node_children_valid(nodep) == FAILURE) {
01413               RETURN_FALSE;
01414        }
01415 
01416        if (nodep->children) {
01417               RETURN_TRUE;
01418        } else {
01419               RETURN_FALSE;
01420        }
01421 }
01422 /* }}} end dom_node_has_child_nodes */
01423 
01424 /* {{{ proto DomNode dom_node_clone_node(boolean deep);
01425 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4
01426 Since: 
01427 */
01428 PHP_FUNCTION(dom_node_clone_node)
01429 {
01430        zval *id;
01431        xmlNode *n, *node;
01432        int ret;
01433        dom_object *intern;
01434        long recursive = 0;
01435 
01436        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
01437               return;
01438        }
01439 
01440        DOM_GET_OBJ(n, id, xmlNodePtr, intern);
01441 
01442        node = xmlDocCopyNode(n, n->doc, recursive);
01443 
01444        if (!node) {
01445               RETURN_FALSE;
01446        }
01447 
01448        /* When deep is false Element nodes still require the attributes 
01449        Following taken from libxml as xmlDocCopyNode doesnt do this */
01450        if (n->type == XML_ELEMENT_NODE && recursive == 0) {
01451               if (n->nsDef != NULL) {
01452                      node->nsDef = xmlCopyNamespaceList(n->nsDef);
01453               }
01454               if (n->ns != NULL) {
01455                      xmlNsPtr ns;
01456                      ns = xmlSearchNs(n->doc, node, n->ns->prefix);
01457                      if (ns == NULL) {
01458                             ns = xmlSearchNs(n->doc, n, n->ns->prefix);
01459                             if (ns != NULL) {
01460                                    xmlNodePtr root = node;
01461 
01462                                    while (root->parent != NULL) {
01463                                           root = root->parent;
01464                                    }
01465                                    node->ns = xmlNewNs(root, ns->href, ns->prefix);
01466                             }
01467                      } else {
01468                             node->ns = ns;
01469                      }
01470               }
01471               if (n->properties != NULL) {
01472                      node->properties = xmlCopyPropList(node, n->properties);
01473               }
01474        }
01475 
01476        /* If document cloned we want a new document proxy */
01477        if (node->doc != n->doc) {
01478               intern = NULL;
01479        }
01480 
01481        DOM_RET_OBJ_EX(node, &ret, intern);
01482 }
01483 /* }}} end dom_node_clone_node */
01484 
01485 /* {{{ proto void dom_node_normalize();
01486 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize
01487 Since: 
01488 */
01489 PHP_FUNCTION(dom_node_normalize)
01490 {
01491        zval *id;
01492        xmlNode *nodep;
01493        dom_object *intern;
01494 
01495        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
01496               return;
01497        }
01498 
01499        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01500 
01501        dom_normalize(nodep TSRMLS_CC);
01502 
01503 }
01504 /* }}} end dom_node_normalize */
01505 
01506 /* {{{ proto boolean dom_node_is_supported(string feature, string version);
01507 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports
01508 Since: DOM Level 2
01509 */
01510 PHP_FUNCTION(dom_node_is_supported)
01511 {
01512        zval *id;
01513        int feature_len, version_len;
01514        char *feature, *version;
01515 
01516        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) {
01517               return;
01518        }
01519 
01520        if (dom_has_feature(feature, version)) {
01521               RETURN_TRUE;
01522        } else {
01523               RETURN_FALSE;
01524        }
01525 }
01526 /* }}} end dom_node_is_supported */
01527 
01528 /* {{{ proto boolean dom_node_has_attributes();
01529 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs
01530 Since: DOM Level 2
01531 */
01532 PHP_FUNCTION(dom_node_has_attributes)
01533 {
01534        zval *id;
01535        xmlNode *nodep;
01536        dom_object *intern;
01537 
01538        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
01539               return;
01540        }
01541 
01542        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01543 
01544        if (nodep->type != XML_ELEMENT_NODE)
01545               RETURN_FALSE;
01546 
01547        if (nodep->properties) {
01548               RETURN_TRUE;
01549        } else {
01550               RETURN_FALSE;
01551        }
01552 }
01553 /* }}} end dom_node_has_attributes */
01554 
01555 /* {{{ proto short dom_node_compare_document_position(DomNode other);
01556 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition
01557 Since: DOM Level 3
01558 */
01559 PHP_FUNCTION(dom_node_compare_document_position)
01560 {
01561  DOM_NOT_IMPLEMENTED();
01562 }
01563 /* }}} end dom_node_compare_document_position */
01564 
01565 /* {{{ proto boolean dom_node_is_same_node(DomNode other);
01566 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
01567 Since: DOM Level 3
01568 */
01569 PHP_FUNCTION(dom_node_is_same_node)
01570 {
01571        zval *id, *node;
01572        xmlNodePtr nodeotherp, nodep;
01573        dom_object *intern, *nodeotherobj;
01574 
01575        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
01576               return;
01577        }
01578 
01579        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01580 
01581        DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
01582 
01583        if (nodep == nodeotherp) {
01584               RETURN_TRUE;
01585        } else {
01586               RETURN_FALSE;
01587        }
01588 }
01589 /* }}} end dom_node_is_same_node */
01590 
01591 /* {{{ proto string dom_node_lookup_prefix(string namespaceURI);
01592 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
01593 Since: DOM Level 3
01594 */
01595 PHP_FUNCTION(dom_node_lookup_prefix)
01596 {
01597        zval *id;
01598        xmlNodePtr nodep, lookupp = NULL;
01599        dom_object *intern;
01600        xmlNsPtr nsptr;
01601        int uri_len = 0;
01602        char *uri;
01603 
01604        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
01605               return;
01606        }
01607 
01608        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01609 
01610        if (uri_len > 0) {
01611               switch (nodep->type) { 
01612                      case XML_ELEMENT_NODE:
01613                             lookupp = nodep;
01614                             break; 
01615                      case XML_DOCUMENT_NODE:
01616                      case XML_HTML_DOCUMENT_NODE:
01617                             lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
01618                             break;
01619                      case XML_ENTITY_NODE : 
01620                      case XML_NOTATION_NODE: 
01621                      case XML_DOCUMENT_FRAG_NODE: 
01622                      case XML_DOCUMENT_TYPE_NODE:
01623                      case XML_DTD_NODE:
01624                             RETURN_NULL();
01625                             break;
01626                      default:
01627                             lookupp =  nodep->parent;
01628               } 
01629 
01630               if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
01631                      if (nsptr->prefix != NULL) {
01632                             RETURN_STRING((char *) nsptr->prefix, 1);
01633                      }
01634               }
01635        }
01636               
01637        RETURN_NULL();
01638 }
01639 /* }}} end dom_node_lookup_prefix */
01640 
01641 /* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI);
01642 URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
01643 Since: DOM Level 3
01644 */
01645 PHP_FUNCTION(dom_node_is_default_namespace)
01646 {
01647        zval *id;
01648        xmlNodePtr nodep;
01649        dom_object *intern;
01650        xmlNsPtr nsptr;
01651        int uri_len = 0;
01652        char *uri;
01653 
01654        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
01655               return;
01656        }
01657 
01658        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01659        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
01660               nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
01661        }
01662 
01663        if (nodep && uri_len > 0) {
01664               nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
01665               if (nsptr && xmlStrEqual(nsptr->href, uri)) {
01666                      RETURN_TRUE;
01667               }
01668        }
01669 
01670        RETURN_FALSE;
01671 }
01672 /* }}} end dom_node_is_default_namespace */
01673 
01674 /* {{{ proto string dom_node_lookup_namespace_uri(string prefix);
01675 URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
01676 Since: DOM Level 3
01677 */
01678 PHP_FUNCTION(dom_node_lookup_namespace_uri)
01679 {
01680        zval *id;
01681        xmlNodePtr nodep;
01682        dom_object *intern;
01683        xmlNsPtr nsptr;
01684        int prefix_len = 0;
01685        char *prefix=NULL;
01686 
01687        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) {
01688               return;
01689        }
01690 
01691        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01692        if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
01693               nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
01694               if (nodep == NULL) {
01695                      RETURN_NULL();
01696               }
01697        }
01698 
01699        nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
01700        if (nsptr && nsptr->href != NULL) {
01701               RETURN_STRING((char *) nsptr->href, 1);
01702        }
01703 
01704        RETURN_NULL();
01705 }
01706 /* }}} end dom_node_lookup_namespace_uri */
01707 
01708 /* {{{ proto boolean dom_node_is_equal_node(DomNode arg);
01709 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode
01710 Since: DOM Level 3
01711 */
01712 PHP_FUNCTION(dom_node_is_equal_node)
01713 {
01714  DOM_NOT_IMPLEMENTED();
01715 }
01716 /* }}} end dom_node_is_equal_node */
01717 
01718 /* {{{ proto DomNode dom_node_get_feature(string feature, string version);
01719 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature
01720 Since: DOM Level 3
01721 */
01722 PHP_FUNCTION(dom_node_get_feature)
01723 {
01724  DOM_NOT_IMPLEMENTED();
01725 }
01726 /* }}} end dom_node_get_feature */
01727 
01728 /* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);
01729 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData
01730 Since: DOM Level 3
01731 */
01732 PHP_FUNCTION(dom_node_set_user_data)
01733 {
01734  DOM_NOT_IMPLEMENTED();
01735 }
01736 /* }}} end dom_node_set_user_data */
01737 
01738 /* {{{ proto mixed dom_node_get_user_data(string key);
01739 URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData
01740 Since: DOM Level 3
01741 */
01742 PHP_FUNCTION(dom_node_get_user_data)
01743 {
01744  DOM_NOT_IMPLEMENTED();
01745 }
01746 /* }}} end dom_node_get_user_data */
01747 
01748 static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
01749 {
01750        zval *id;
01751        zval *xpath_array=NULL, *ns_prefixes=NULL;
01752        xmlNodePtr nodep;
01753        xmlDocPtr docp;
01754        xmlNodeSetPtr nodeset = NULL;
01755        dom_object *intern;
01756        zend_bool exclusive=0, with_comments=0;
01757        xmlChar **inclusive_ns_prefixes = NULL;
01758        char *file = NULL;
01759        int ret = -1, file_len = 0;
01760        xmlOutputBufferPtr buf;
01761        xmlXPathContextPtr ctxp=NULL;
01762        xmlXPathObjectPtr xpathobjp=NULL;
01763 
01764        if (mode == 0) {
01765               if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
01766                      "O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments, 
01767                      &xpath_array, &ns_prefixes) == FAILURE) {
01768                      return;
01769               }
01770        } else {
01771               if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), 
01772                      "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive, 
01773                      &with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
01774                      return;
01775               }
01776        }
01777 
01778        DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
01779 
01780        docp = nodep->doc;
01781 
01782        if (! docp) {
01783               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document");
01784               RETURN_FALSE;
01785        }
01786 
01787        if (xpath_array == NULL) {
01788               if (nodep->type != XML_DOCUMENT_NODE) {
01789                      ctxp = xmlXPathNewContext(docp);
01790                      ctxp->node = nodep;
01791                      xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp);
01792                      ctxp->node = NULL;
01793                      if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
01794                             nodeset = xpathobjp->nodesetval;
01795                      } else {
01796                             if (xpathobjp) {
01797                                    xmlXPathFreeObject(xpathobjp);
01798                             }
01799                             xmlXPathFreeContext(ctxp);
01800                             php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
01801                             RETURN_FALSE;
01802                      }
01803               }
01804        } else {
01805               /*xpath query from xpath_array */
01806               HashTable *ht = Z_ARRVAL_P(xpath_array);
01807               zval **tmp;
01808               char *xquery;
01809 
01810               if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS &&
01811                   Z_TYPE_PP(tmp) == IS_STRING) {
01812                      xquery = Z_STRVAL_PP(tmp);
01813               } else {
01814                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string");
01815                      RETURN_FALSE;
01816               }
01817 
01818               ctxp = xmlXPathNewContext(docp);
01819               ctxp->node = nodep;
01820 
01821               if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS &&
01822                   Z_TYPE_PP(tmp) == IS_ARRAY) {
01823                      zval **tmpns;
01824                      while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) {
01825                             if (Z_TYPE_PP(tmpns) == IS_STRING) {
01826                                    char *prefix;
01827                                    ulong idx;
01828                                    int prefix_key_len;
01829 
01830                                    if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp), 
01831                                           &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
01832                                           xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns));
01833                                    }
01834                             }
01835                             zend_hash_move_forward(Z_ARRVAL_PP(tmp));
01836                      }
01837               }
01838 
01839               xpathobjp = xmlXPathEvalExpression(xquery, ctxp);
01840               ctxp->node = NULL;
01841               if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
01842                      nodeset = xpathobjp->nodesetval;
01843               } else {
01844                      if (xpathobjp) {
01845                             xmlXPathFreeObject(xpathobjp);
01846                      }
01847                      xmlXPathFreeContext(ctxp);
01848                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
01849                      RETURN_FALSE;
01850               }
01851        }
01852 
01853        if (ns_prefixes != NULL) {
01854               if (exclusive) {
01855                      zval **tmpns;
01856                      int nscount = 0;
01857 
01858                      inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1,
01859                             sizeof(xmlChar *), 0);
01860                      while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) {
01861                             if (Z_TYPE_PP(tmpns) == IS_STRING) {
01862                                    inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns);
01863                             }
01864                             zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes));
01865                      }
01866                      inclusive_ns_prefixes[nscount] = NULL;
01867               } else {
01868                      php_error_docref(NULL TSRMLS_CC, E_NOTICE, 
01869                             "Inclusive namespace prefixes only allowed in exclusive mode.");
01870               }
01871        }
01872 
01873        if (mode == 1) {
01874               buf = xmlOutputBufferCreateFilename(file, NULL, 0);
01875        } else {
01876               buf = xmlAllocOutputBuffer(NULL);
01877        }
01878 
01879     if (buf != NULL) {
01880               ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
01881                      with_comments, buf);
01882        }
01883 
01884        if (inclusive_ns_prefixes != NULL) {
01885               efree(inclusive_ns_prefixes);
01886        }
01887        if (xpathobjp != NULL) {
01888               xmlXPathFreeObject(xpathobjp);
01889        }
01890        if (ctxp != NULL) {
01891               xmlXPathFreeContext(ctxp);
01892        }
01893 
01894     if (buf == NULL || ret < 0) {
01895         RETVAL_FALSE;
01896     } else {
01897               if (mode == 0) {
01898                      ret = buf->buffer->use;
01899                      if (ret > 0) {
01900                             RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
01901                      } else {
01902                             RETVAL_EMPTY_STRING();
01903                      }
01904               }
01905     }
01906 
01907        if (buf) {
01908               int bytes;
01909 
01910               bytes = xmlOutputBufferClose(buf);
01911               if (mode == 1 && (ret >= 0)) {
01912                      RETURN_LONG(bytes);
01913               }
01914        }
01915 }
01916 /* }}} */
01917 
01918 /* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
01919    Canonicalize nodes to a string */
01920 PHP_METHOD(domnode, C14N)
01921 {
01922        dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
01923 }
01924 /* }}} */
01925 
01926 /* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
01927    Canonicalize nodes to a file */
01928 PHP_METHOD(domnode, C14NFile)
01929 {
01930        dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
01931 }
01932 /* }}} */
01933 
01934 /* {{{ proto int DOMNode::getNodePath()
01935    Gets an xpath for a node */
01936 PHP_METHOD(domnode, getNodePath)
01937 {
01938        zval *id;
01939        xmlNode *nodep;
01940        dom_object *intern;
01941        char *value;
01942        
01943        DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
01944 
01945        value = xmlGetNodePath(nodep);
01946        if (value == NULL) {
01947               RETURN_NULL();
01948        } else {
01949               RETVAL_STRING(value, 1);
01950               xmlFree(value);
01951        }
01952 }
01953 /* }}} */
01954 
01955 /* {{{ proto int DOMNode::getLineNo()
01956    Gets line number for a node */
01957 PHP_METHOD(domnode, getLineNo)
01958 {
01959        zval *id;
01960        xmlNode *nodep;
01961        dom_object *intern;
01962        
01963        if (zend_parse_parameters_none() == FAILURE) {
01964               return;
01965        }
01966 
01967        DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
01968 
01969        RETURN_LONG(xmlGetLineNo(nodep));
01970 }
01971 /* }}} */
01972 
01973 #endif
01974 
01975 /*
01976  * Local variables:
01977  * tab-width: 4
01978  * c-basic-offset: 4
01979  * End:
01980  * vim600: noet sw=4 ts=4 fdm=marker
01981  * vim<600: noet sw=4 ts=4
01982  */