From: Rob Richards Date: Mon, 8 Sep 2003 18:28:35 +0000 (+0000) Subject: move some document properties internally X-Git-Tag: RELEASE_0_7~170 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=315bf401ba390c1a7e6d506308824bac1c535d01;p=php move some document properties internally add xpath namespace support (by Shane) --- diff --git a/ext/dom/document.c b/ext/dom/document.c index aa6a4cc240..1492dee1dc 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -85,39 +85,6 @@ zend_function_entry php_dom_document_class_functions[] = { {NULL, NULL, NULL} }; -/* {{{ void add_domdocument_properties(zval *id) */ -void add_domdocument_properties(zval *id TSRMLS_DC) { - add_property_bool(id, "formatOutput", 0); - add_property_bool(id, "validateOnParse", 0); - add_property_bool(id, "resolveExternals", 0); - add_property_bool(id, "preserveWhiteSpace", 1); - add_property_bool(id, "substituteEntities", 0); -} -/* }}} end add_domdocument_properties */ - -/* {{{ static int dom_document_get_property_int(zval *id, char *property TSRMLS_DC) */ -static int dom_document_get_property_int(zval *id, char *property TSRMLS_DC) { - zval *format, *member; - zend_object_handlers *std_hnd; - int retformat = 0; - - MAKE_STD_ZVAL(member); - ZVAL_STRING(member, property, 1); - - std_hnd = zend_get_std_object_handlers(); - format = std_hnd->read_property(id, member, 0 TSRMLS_CC); - - if (format->type == IS_BOOL) { - retformat = Z_BVAL_P(format); - } - - zval_dtor(member); - FREE_ZVAL(member); - - return retformat; -} -/* }}} end dom_document_get_property_int */ - static void php_dom_validate_error(void *ctx, const char *msg, ...) { char *buf; @@ -386,8 +353,6 @@ int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC) /* }}} */ - - /* {{{ proto strict_error_checking boolean readonly=no URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking @@ -395,9 +360,12 @@ Since: DOM Level 3 */ int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC) { + dom_doc_props *doc_prop; + ALLOC_ZVAL(*retval); if (obj->document) { - ZVAL_BOOL(*retval, obj->document->stricterror); + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->stricterror); } else { ZVAL_FALSE(*retval); } @@ -406,11 +374,11 @@ int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRML int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC) { - int stricterror; + dom_doc_props *doc_prop; if (obj->document && newval->type == IS_BOOL) { - stricterror = Z_LVAL_P(newval); - obj->document->stricterror = stricterror; + doc_prop = dom_get_doc_props(obj->document); + doc_prop->stricterror = Z_LVAL_P(newval); } return SUCCESS; @@ -418,6 +386,158 @@ int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRML /* }}} */ +/* {{{ proto formatOutput boolean +readonly=no +*/ +int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->formatoutput); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + if (obj->document && newval->type == IS_BOOL) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->formatoutput = Z_LVAL_P(newval); + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ proto validateonParse boolean +readonly=no +*/ +int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->validateonparse); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + if (obj->document && newval->type == IS_BOOL) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->validateonparse = Z_LVAL_P(newval); + } + + return SUCCESS; +} +/* }}} */ + + +/* {{{ proto resolveExternals boolean +readonly=no +*/ +int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->resolveexternals); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + if (obj->document && newval->type == IS_BOOL) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->resolveexternals = Z_LVAL_P(newval); + } + + return SUCCESS; +} +/* }}} */ + + +/* {{{ proto preserveWhiteSpace boolean +readonly=no +*/ +int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->preservewhitespace); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + if (obj->document && newval->type == IS_BOOL) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->preservewhitespace = Z_LVAL_P(newval); + } + + return SUCCESS; +} +/* }}} */ + + +/* {{{ proto substituteEntities boolean +readonly=no +*/ +int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + ALLOC_ZVAL(*retval); + if (obj->document) { + doc_prop = dom_get_doc_props(obj->document); + ZVAL_BOOL(*retval, doc_prop->substituteentities); + } else { + ZVAL_FALSE(*retval); + } + return SUCCESS; +} + +int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC) +{ + dom_doc_props *doc_prop; + + if (obj->document && newval->type == IS_BOOL) { + doc_prop = dom_get_doc_props(obj->document); + doc_prop->substituteentities = Z_LVAL_P(newval); + } + + return SUCCESS; +} +/* }}} */ /* {{{ proto document_uri string @@ -1078,8 +1198,6 @@ PHP_FUNCTION(dom_document_document) php_dom_set_object(intern, (xmlNodePtr) docp TSRMLS_CC); } - - add_domdocument_properties(id TSRMLS_CC); } /* }}} end dom_document_document */ @@ -1088,18 +1206,24 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC) xmlDocPtr ret; xmlParserCtxtPtr ctxt; char *directory = NULL; + dom_doc_props *doc_props; + dom_object *intern; + dom_ref_obj *document = NULL; int validate, resolve_externals, keep_blanks, substitute_ent; if (id != NULL) { - validate = dom_document_get_property_int(id, "validateOnParse" TSRMLS_CC); - resolve_externals = dom_document_get_property_int(id, "resolveExternals" TSRMLS_CC); - keep_blanks = dom_document_get_property_int(id, "preserveWhiteSpace" TSRMLS_CC); - substitute_ent = dom_document_get_property_int(id, "substituteEntities" TSRMLS_CC); - } else { - validate = 0; - resolve_externals = 0; - keep_blanks = 1; - substitute_ent = 0; + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + document = intern->document; + } + + doc_props = dom_get_doc_props(document); + validate = doc_props->validateonparse; + resolve_externals = doc_props->resolveexternals; + keep_blanks = doc_props->preservewhitespace; + substitute_ent = doc_props->substituteentities; + + if (document == NULL) { + efree(doc_props); } xmlInitParser(); @@ -1123,7 +1247,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC) ctxt->recovery = 0; ctxt->validate = validate; - ctxt->loadsubset = resolve_externals; + ctxt->loadsubset = (resolve_externals * XML_COMPLETE_ATTRS); ctxt->keepBlanks = keep_blanks; ctxt->replaceEntities = substitute_ent; @@ -1153,6 +1277,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source TSRMLS_DC) static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { zval *id, *rv = NULL; xmlDoc *docp = NULL, *newdoc; + dom_doc_props *doc_prop; dom_object *intern; char *source; int source_len, refcount, ret; @@ -1178,8 +1303,11 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); if (intern != NULL) { docp = (xmlDocPtr) dom_object_get_node(intern); + doc_prop = NULL; if (docp != NULL) { decrement_node_ptr(intern TSRMLS_CC); + doc_prop = intern->document->doc_props; + intern->document->doc_props = NULL; refcount = decrement_document_reference(intern TSRMLS_CC); if (refcount != 0) { docp->_private = NULL; @@ -1187,6 +1315,7 @@ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) { } intern->document = NULL; increment_document_reference(intern, newdoc TSRMLS_CC); + intern->document->doc_props = doc_prop; } php_dom_set_object(intern, (xmlNodePtr) newdoc TSRMLS_CC); @@ -1227,6 +1356,7 @@ PHP_FUNCTION(dom_document_save) xmlDoc *docp; int file_len, bytes, format; dom_object *intern; + dom_doc_props *doc_props; char *file; DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); @@ -1240,7 +1370,9 @@ PHP_FUNCTION(dom_document_save) } /* encoding handled by property on doc */ - format = dom_document_get_property_int(id, "formatOutput" TSRMLS_CC); + + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; bytes = xmlSaveFormatFileEnc(file, docp, NULL, format); if (bytes == -1) { @@ -1262,6 +1394,7 @@ PHP_FUNCTION(dom_document_savexml) xmlBufferPtr buf; xmlChar *mem; dom_object *intern, *nodeobj; + dom_doc_props *doc_props; int size, format; DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); @@ -1270,7 +1403,8 @@ PHP_FUNCTION(dom_document_savexml) return; } - format = dom_document_get_property_int(id, "formatOutput" TSRMLS_CC); + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; if (nodep != NULL) { /* Dump contents of Node */ @@ -1341,6 +1475,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) zval *id, *rv = NULL; xmlDoc *docp = NULL, *newdoc; dom_object *intern; + dom_doc_props *doc_prop; char *source; int source_len, refcount, ret; @@ -1366,8 +1501,11 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); if (intern != NULL) { docp = (xmlDocPtr) dom_object_get_node(intern); + doc_prop = NULL; if (docp != NULL) { decrement_node_ptr(intern TSRMLS_CC); + doc_prop = intern->document->doc_props; + intern->document->doc_props = NULL; refcount = decrement_document_reference(intern TSRMLS_CC); if (refcount != 0) { docp->_private = NULL; @@ -1375,6 +1513,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) } intern->document = NULL; increment_document_reference(intern, newdoc TSRMLS_CC); + intern->document->doc_props = doc_prop; } php_dom_set_object(intern, (xmlNodePtr) newdoc TSRMLS_CC); @@ -1412,6 +1551,7 @@ PHP_FUNCTION(dom_document_save_html_file) xmlDoc *docp; int file_len, bytes, format; dom_object *intern; + dom_doc_props *doc_props; char *file; DOM_GET_THIS_OBJ(docp, id, xmlDocPtr, intern); @@ -1425,7 +1565,9 @@ PHP_FUNCTION(dom_document_save_html_file) } /* encoding handled by property on doc */ - format = dom_document_get_property_int(id, "formatOutput" TSRMLS_CC); + + doc_props = dom_get_doc_props(intern->document); + format = doc_props->formatoutput; bytes = htmlSaveFileFormat(file, docp, NULL, format); if (bytes == -1) { diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h index 287ee5651d..b8406bee98 100644 --- a/ext/dom/dom_fe.h +++ b/ext/dom/dom_fe.h @@ -246,6 +246,7 @@ PHP_FUNCTION(dom_string_extend_find_offset32); #if defined(LIBXML_XPATH_ENABLED) /* xpath methods */ PHP_FUNCTION(dom_xpath_xpath); +PHP_FUNCTION(dom_xpath_register_ns); PHP_FUNCTION(dom_xpath_query); #endif diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h index b61f8e72a4..30538df6b7 100644 --- a/ext/dom/dom_properties.h +++ b/ext/dom/dom_properties.h @@ -51,6 +51,16 @@ int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRML int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC); int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC); int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_format_output_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_validate_on_parse_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_resolve_externals_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_preserve_whitespace_write(dom_object *obj, zval *newval TSRMLS_DC); +int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC); +int dom_document_substitue_entities_write(dom_object *obj, zval *newval TSRMLS_DC); /* documenttype properties */ int dom_documenttype_name_read(dom_object *obj, zval **retval TSRMLS_DC); diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index c6870d628e..6654ac5946 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -114,15 +114,45 @@ int dom_node_children_valid(xmlNodePtr node) { } /* }}} end dom_node_children_valid */ -int dom_get_strict_error(dom_ref_obj *document) { - if (document) { - return document->stricterror; +/* {{{ dom_get_doc_props() */ +dom_doc_propsptr dom_get_doc_props(dom_ref_obj *document) +{ + dom_doc_props *doc_props; + + if (document && document->doc_props) { + return document->doc_props; } else { - return 1; + doc_props = emalloc(sizeof(dom_doc_props)); + doc_props->formatoutput = 0; + doc_props->validateonparse = 0; + doc_props->resolveexternals = 0; + doc_props->preservewhitespace = 1; + doc_props->substituteentities = 0; + doc_props->stricterror = 1; + if (document) { + document->doc_props = doc_props; + } + return doc_props; + } +} +/* }}} */ + +/* {{{ dom_get_strict_error() */ +int dom_get_strict_error(dom_ref_obj *document) { + int stricterror; + dom_doc_props *doc_props; + + doc_props = dom_get_doc_props(document); + stricterror = doc_props->stricterror; + if (document == NULL) { + efree(doc_props); } + + return stricterror; } +/* }}} */ -/* {{{ int increment_document_reference(dom_object *object) */ +/* {{{ increment_document_reference() */ int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC) { int ret_refcount = -1; @@ -134,7 +164,7 @@ int increment_document_reference(dom_object *object, xmlDocPtr docp TSRMLS_DC) { object->document = emalloc(sizeof(dom_ref_obj)); object->document->ptr = docp; object->document->refcount = ret_refcount; - object->document->stricterror = 1; + object->document->doc_props = NULL; } return ret_refcount; @@ -153,6 +183,9 @@ int decrement_document_reference(dom_object *object TSRMLS_DC) { xmlFreeDoc((xmlDoc *) object->document->ptr); object->document->ptr = NULL; } + if (object->document->doc_props != NULL) { + efree(object->document->doc_props); + } efree(object->document); } object->document = NULL; @@ -465,6 +498,12 @@ PHP_MINIT_FUNCTION(dom) dom_register_prop_handler(&dom_document_prop_handlers, "strictErrorChecking", dom_document_strict_error_checking_read, dom_document_strict_error_checking_write TSRMLS_CC); dom_register_prop_handler(&dom_document_prop_handlers, "documentURI", dom_document_document_uri_read, dom_document_document_uri_write TSRMLS_CC); dom_register_prop_handler(&dom_document_prop_handlers, "config", dom_document_config_read, NULL TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "formatOutput", dom_document_format_output_read, dom_document_format_output_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "validateOnParse", dom_document_validate_on_parse_read, dom_document_validate_on_parse_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "resolveExternals", dom_document_resolve_externals_read, dom_document_resolve_externals_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "preserveWhiteSpace", dom_document_preserve_whitespace_read, dom_document_preserve_whitespace_write TSRMLS_CC); + dom_register_prop_handler(&dom_document_prop_handlers, "substituteEntities", dom_document_substitue_entities_read, dom_document_substitue_entities_write TSRMLS_CC); + zend_hash_merge(&dom_document_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0); zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_document_prop_handlers, sizeof(dom_document_prop_handlers), NULL); @@ -1074,10 +1113,7 @@ zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *wrapper_in, zval * } object_init_ex(wrapper, ce); - /* Add object properties not needing function calls */ - if (obj->type == XML_DOCUMENT_NODE || obj->type == XML_HTML_DOCUMENT_NODE) { - add_domdocument_properties(wrapper TSRMLS_CC); - } + intern = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC); if (obj->doc != NULL) { if (domobj != NULL) { diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 6946b87ef8..da7c75f18c 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -66,6 +66,7 @@ extern zend_module_entry dom_module_entry; void php_dom_set_object(dom_object *object, xmlNodePtr obj TSRMLS_DC); dom_object *dom_object_get_data(xmlNodePtr obj); xmlNodePtr dom_object_get_node(dom_object *obj); +dom_doc_propsptr dom_get_doc_props(dom_ref_obj *document); zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC); #if defined(LIBXML_XPATH_ENABLED) zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC); @@ -86,7 +87,6 @@ void dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local void php_dom_create_implementation(zval **retval TSRMLS_DC); int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child); int dom_has_feature(char *feature, char *version); -void add_domdocument_properties(zval *id TSRMLS_DC); int dom_node_is_read_only(xmlNodePtr node); int dom_node_children_valid(xmlNodePtr node); diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h index f309da5d96..92205dc25e 100644 --- a/ext/dom/xml_common.h +++ b/ext/dom/xml_common.h @@ -22,10 +22,21 @@ #ifndef PHP_XML_COMMON_H #define PHP_XML_COMMON_H +typedef struct _dom_doc_props { + int formatoutput; + int validateonparse; + int resolveexternals; + int preservewhitespace; + int substituteentities; + int stricterror; +} dom_doc_props; + +typedef dom_doc_props *dom_doc_propsptr; + typedef struct _dom_ref_obj { void *ptr; int refcount; - int stricterror; + dom_doc_props *doc_props; } dom_ref_obj; typedef struct _node_ptr { diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 73092bba99..0709be3823 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -36,6 +36,7 @@ zend_function_entry php_dom_xpath_class_functions[] = { PHP_FALIAS(domxpath, dom_xpath_xpath, NULL) + PHP_FALIAS(register_namespace, dom_xpath_register_ns, NULL) PHP_FALIAS(query, dom_xpath_query, NULL) {NULL, NULL, NULL} }; @@ -98,6 +99,35 @@ int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC) return SUCCESS; } +/* {{{ proto boolean dom_xpath_register_ns(string prefix, string uri); */ +PHP_FUNCTION(dom_xpath_register_ns) +{ + zval *id; + xmlXPathContextPtr ctxp; + int prefix_len, ns_uri_len; + dom_object *intern; + unsigned char *prefix, *ns_uri; + + DOM_GET_THIS(id); + + intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); + + ctxp = (xmlXPathContextPtr) intern->ptr; + if (ctxp == NULL) { + php_error(E_WARNING, "Invalid XPath Context"); + RETURN_FALSE; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) { + RETURN_FALSE; + } + fprintf(stderr,"register %s=%s\n",prefix, ns_uri); + if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) { + RETURN_FALSE + } + RETURN_TRUE; +} + /* {{{ proto domnodelist dom_xpath_query(string expr [,domNode context]); */ PHP_FUNCTION(dom_xpath_query) { @@ -105,9 +135,11 @@ PHP_FUNCTION(dom_xpath_query) xmlXPathContextPtr ctxp; xmlNodePtr nodep = NULL; xmlXPathObjectPtr xpathobjp; - int expr_len, ret; + int expr_len, ret, nsnbr = 0; dom_object *intern, *nodeobj; char *expr; + xmlDoc *docp = NULL; + xmlNsPtr *ns; DOM_GET_THIS(id); @@ -119,21 +151,50 @@ PHP_FUNCTION(dom_xpath_query) RETURN_FALSE; } + docp = (xmlDocPtr) ctxp->doc; + if (docp == NULL) { + php_error(E_WARNING, "Invalid XPath Document Pointer"); + RETURN_FALSE; + } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|o", &expr, &expr_len, &context) == FAILURE) { - return; + RETURN_FALSE; } if (context != NULL) { DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj); } + if (!nodep) { + nodep = xmlDocGetRootElement(docp); + } + + if (docp != nodep->doc) { + php_error(E_WARNING, "Node From Wrong Document"); + RETURN_FALSE; + } + ctxp->node = nodep; + /* Register namespaces in the node */ + ns = xmlGetNsList(docp, nodep); + + if (ns != NULL) { + while (ns[nsnbr] != NULL) + nsnbr++; + } + + + ctxp->namespaces = ns; + ctxp->nsNr = nsnbr; + xpathobjp = xmlXPathEvalExpression(expr, ctxp); ctxp->node = NULL; - if (!xpathobjp) { - RETURN_FALSE; + if (ns != NULL) { + xmlFree(ns); + ctxp->namespaces = NULL; + ctxp->nsNr = 0; } if (xpathobjp->type == XPATH_NODESET) { @@ -155,8 +216,6 @@ PHP_FUNCTION(dom_xpath_query) child = php_dom_create_object(node, &ret, NULL, child, intern TSRMLS_CC); add_next_index_zval(return_value, child); } - } else { - printf("Type: %d", xpathobjp->type); } xmlXPathFreeObject(xpathobjp);