summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/dom/document.c250
-rw-r--r--ext/dom/dom_fe.h1
-rw-r--r--ext/dom/dom_properties.h10
-rw-r--r--ext/dom/php_dom.c56
-rw-r--r--ext/dom/php_dom.h2
-rw-r--r--ext/dom/xml_common.h13
-rw-r--r--ext/dom/xpath.c71
7 files changed, 331 insertions, 72 deletions
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);