From: Jaroslaw Kolakowski Date: Tue, 8 Jan 2002 00:31:26 +0000 (+0000) Subject: - Added functions: htmldoc(), htmldocfile(), domxml_htmldumpmem(). X-Git-Tag: PRE_ISSET_PATCH~254 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=415d5cbb75d91331d05ff77f7e3f3c2ae981dff1;p=php - Added functions: htmldoc(), htmldocfile(), domxml_htmldumpmem(). - Added error handling for the libxml library. - Added preliminary DOM XSLT support: -- uses the libxslt library, -- operates on DOM objects, not strings, -- functions: domxml_xslt_process(), domxml_xslt_version(). --- diff --git a/ext/domxml/config.m4 b/ext/domxml/config.m4 index 9004c3b8a6..1f8ebea72e 100644 --- a/ext/domxml/config.m4 +++ b/ext/domxml/config.m4 @@ -64,3 +64,52 @@ if test "$PHP_DOM" != "no"; then PHP_EXTENSION(domxml, $ext_shared) PHP_SUBST(DOMXML_SHARED_LIBADD) fi + +AC_DEFUN(PHP_DOM_XSLT_CHECK_VERSION,[ + old_CPPFLAGS=$CPPFLAGS + CPPFLAGS=-I$DOMXSLT_DIR/include + AC_MSG_CHECKING(for libxslt version) + AC_EGREP_CPP(yes,[ + #include + #if LIBXSLT_VERSION >= 10003 + yes + #endif + ],[ + AC_MSG_RESULT(>= 1.0.3) + ],[ + AC_MSG_ERROR(libxslt version 1.0.3 or greater required.) + ]) + CPPFLAGS=$old_CPPFLAGS +]) + +PHP_ARG_WITH(dom-xslt, for DOM XSLT support, +[ --with-dom-xslt[=DIR] Include DOM XSLT support (requires libxslt >= 1.0.3). + DIR is the libxslt install directory.]) + +if test "$PHP_DOM_XSLT" != "no"; then + + if test -r $PHP_DOM_XSLT/include/libxslt/transform.h; then + DOMXSLT_DIR=$PHP_DOM_XSLT + else + for i in /usr/local /usr; do + test -r $i/include/libxslt/transform.h && DOMXSLT_DIR=$i + done + fi + + if test -z "$DOMXSLT_DIR"; then + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Please reinstall the libxslt >= 1.0.3 distribution) + fi + + PHP_DOM_XSLT_CHECK_VERSION + + PHP_ADD_LIBRARY_WITH_PATH(xslt, $DOMXSLT_DIR/lib, DOMXML_SHARED_LIBADD) + PHP_ADD_INCLUDE($DOMXSLT_DIR/include) + + if test "$DOMXML_DIR" = "no"; then + AC_MSG_ERROR(DOMXSLT requires DOMXML. Use --with-dom=) + fi + + AC_DEFINE(HAVE_DOMXSLT,1,[ ]) + PHP_SUBST(DOMXML_SHARED_LIBADD) +fi diff --git a/ext/domxml/php_domxml.c b/ext/domxml/php_domxml.c index d3c48a569d..0c3d8204c4 100644 --- a/ext/domxml/php_domxml.c +++ b/ext/domxml/php_domxml.c @@ -153,9 +153,16 @@ static zend_function_entry domxml_functions[] = { PHP_FE(domxml_version, NULL) PHP_FE(xmldoc, NULL) PHP_FE(xmldocfile, NULL) +#if defined(LIBXML_HTML_ENABLED) + PHP_FE(htmldoc, NULL) + PHP_FE(htmldocfile, NULL) +#endif PHP_FE(xmltree, NULL) PHP_FE(domxml_add_root, NULL) PHP_FE(domxml_dumpmem, NULL) +#if defined(LIBXML_HTML_ENABLED) + PHP_FE(domxml_htmldumpmem, NULL) +#endif PHP_FE(domxml_node_attributes, NULL) PHP_FE(domxml_elem_get_attribute, NULL) PHP_FE(domxml_elem_set_attribute, NULL) @@ -175,6 +182,10 @@ static zend_function_entry domxml_functions[] = { PHP_FE(xptr_new_context, NULL) PHP_FE(xptr_eval, NULL) #endif +#if HAVE_DOMXSLT + PHP_FE(domxml_xslt_version, NULL) + PHP_FE(domxml_xslt_process, NULL) +#endif PHP_FALIAS(domxml_root, domxml_doc_document_element, NULL) PHP_FALIAS(domxml_attributes, domxml_node_attributes, NULL) @@ -211,6 +222,9 @@ static function_entry php_domxmldoc_class_functions[] = { PHP_FALIAS(imported_node, domxml_doc_imported_node, NULL) PHP_FALIAS(dtd, domxml_intdtd, NULL) PHP_FALIAS(dumpmem, domxml_dumpmem, NULL) +#if defined(LIBXML_HTML_ENABLED) + PHP_FALIAS(htmldumpmem, domxml_htmldumpmem, NULL) +#endif #if defined(LIBXML_XPATH_ENABLED) PHP_FALIAS(xpath_init, xpath_init, NULL) PHP_FALIAS(xpath_new_context, xpath_new_context, NULL) @@ -859,8 +873,10 @@ static zval *php_domobject_new(xmlNodePtr obj, int *found TSRMLS_DC) } case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: { xmlDocPtr docp = (xmlDocPtr) obj; + object_init_ex(wrapper, domxmldoc_class_entry); rsrc_type = le_domxmldocp; if (docp->name) @@ -871,7 +887,10 @@ static zval *php_domobject_new(xmlNodePtr obj, int *found TSRMLS_DC) add_property_stringl(wrapper, "url", (char *) docp->URL, strlen(docp->URL), 1); else add_property_stringl(wrapper, "url", "", 0, 1); - add_property_stringl(wrapper, "version", (char *) docp->version, strlen(docp->version), 1); + if (docp->version) + add_property_stringl(wrapper, "version", (char *) docp->version, strlen(docp->version), 1); + else + add_property_stringl(wrapper, "version", "", 0, 1); if (docp->encoding) add_property_stringl(wrapper, "encoding", (char *) docp->encoding, strlen(docp->encoding), 1); add_property_long(wrapper, "standalone", docp->standalone); @@ -919,6 +938,17 @@ static zval *php_domobject_new(xmlNodePtr obj, int *found TSRMLS_DC) } +static void domxml_error(void *ctx, const char *msg, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, msg); + vsnprintf(buf, 1024, msg, ap); + va_end(ap); + php_error(E_WARNING, buf); +} + + PHP_RINIT_FUNCTION(domxml) { return SUCCESS; @@ -1048,6 +1078,11 @@ PHP_MINIT_FUNCTION(domxml) REGISTER_LONG_CONSTANT("XPATH_USERS", XPATH_USERS, CONST_CS | CONST_PERSISTENT); #endif + xmlSetGenericErrorFunc(xmlGenericErrorContext, (xmlGenericErrorFunc)domxml_error); +#if HAVE_DOMXSLT + xsltSetGenericErrorFunc(xsltGenericErrorContext, (xmlGenericErrorFunc)domxml_error); +#endif + return SUCCESS; } @@ -1073,11 +1108,18 @@ PHP_MINFO_FUNCTION(domxml) php_info_print_table_start(); php_info_print_table_row(2, "DOM/XML", "enabled"); php_info_print_table_row(2, "libxml Version", LIBXML_DOTTED_VERSION); +#if defined(LIBXML_HTML_ENABLED) + php_info_print_table_row(2, "HTML Support", "enabled"); +#endif #if defined(LIBXML_XPATH_ENABLED) php_info_print_table_row(2, "XPath Support", "enabled"); #endif #if defined(LIBXML_XPTR_ENABLED) php_info_print_table_row(2, "XPointer Support", "enabled"); +#endif +#if HAVE_DOMXSLT + php_info_print_table_row(2, "DOM/XSLT", "enabled"); + php_info_print_table_row(2, "libxslt Version", LIBXSLT_DOTTED_VERSION); #endif php_info_print_table_end(); } @@ -1566,7 +1608,7 @@ PHP_FUNCTION(domxml_node_children) /* Even if the nodep is a XML_DOCUMENT_NODE the type is at the same position. */ - if (Z_TYPE_P(nodep) == XML_DOCUMENT_NODE) + if ((Z_TYPE_P(nodep) == XML_DOCUMENT_NODE) || (Z_TYPE_P(nodep) == XML_HTML_DOCUMENT_NODE)) last = ((xmlDoc *) nodep)->children; else last = nodep->children; @@ -2436,6 +2478,92 @@ PHP_FUNCTION(xmldocfile) } /* }}} */ +#if defined(LIBXML_HTML_ENABLED) +/* {{{ proto string domxml_htmldumpmem([int doc_handle]) + Dumps document into string */ +PHP_FUNCTION(domxml_htmldumpmem) +{ + zval *id; + xmlDoc *docp; + xmlChar *mem; + int size; + + DOMXML_PARAM_NONE(docp, id, le_domxmldocp); + + htmlDocDumpMemory(docp, &mem, &size); + if (!size) { + RETURN_FALSE; + } + RETURN_STRINGL(mem, size, 1); +} +/* }}} */ + +/* {{{ proto object htmldoc(string htmldoc) + Creates DOM object of HTML document */ +PHP_FUNCTION(htmldoc) +{ + zval *rv; + xmlDoc *docp; + int ret; + char *buffer; + int buffer_len; + zend_bool from_file = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &buffer, &buffer_len, &from_file) == FAILURE) { + return; + } + + if (from_file) { + docp = htmlParseFile(buffer, NULL); + } else { + docp = htmlParseDoc(buffer, NULL); + } + if (!docp) + RETURN_FALSE; + + DOMXML_RET_OBJ(rv, (xmlNodePtr) docp, &ret); +} +/* }}} */ + +/* {{{ proto object htmldocfile(string filename) + Creates DOM object of HTML document in file*/ +PHP_FUNCTION(htmldocfile) +{ + zval *rv; + xmlDoc *docp; + int ret, file_len; + char *file; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) { + return; + } + + docp = htmlParseFile(file, NULL); + if (!docp) { + RETURN_FALSE; + } + + DOMXML_RET_OBJ(rv, (xmlNodePtr) docp, &ret); + + add_property_resource(return_value, "doc", ret); + if (docp->name) + add_property_stringl(return_value, "name", (char *) docp->name, strlen(docp->name), 1); + if (docp->URL) + add_property_stringl(return_value, "url", (char *) docp->URL, strlen(docp->URL), 1); + if (docp->version) + add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1); +/* add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1);*/ + if (docp->encoding) + add_property_stringl(return_value, "encoding", (char *) docp->encoding, strlen(docp->encoding), 1); + add_property_long(return_value, "standalone", docp->standalone); + add_property_long(return_value, "type", Z_TYPE_P(docp)); + add_property_long(return_value, "compression", docp->compression); + add_property_long(return_value, "charset", docp->charset); + zend_list_addref(ret); +} +/* }}} */ +#endif /* defined(LIBXML_HTML_ENABLED) */ + /* {{{ proto bool domxml_node_text_concat(string content) Add string tocontent of a node */ PHP_FUNCTION(domxml_node_text_concat) @@ -2894,6 +3022,117 @@ PHP_FUNCTION(domxml_version) } /* }}} */ +#if HAVE_DOMXSLT +/* {{{ _php_libxslt_ht_char() + Translates a PHP array to a libxslt character array */ +static void _php_libxslt_ht_char(HashTable *php, char **arr) +{ + zval **value; + char *string_key = NULL; + ulong num_key; + int i = 0; + + for (zend_hash_internal_pointer_reset(php); + zend_hash_get_current_data(php, (void **)&value) == SUCCESS; + zend_hash_move_forward(php)) { + + SEPARATE_ZVAL(value); + convert_to_string_ex(value); + + if (zend_hash_get_current_key(php, &string_key, &num_key, 1) != HASH_KEY_IS_STRING) { + php_error(E_WARNING, "Not a string key in the parameters array"); + } + else + { + arr[i++] = string_key; + arr[i++] = Z_STRVAL_PP(value); + } + } + arr[i++] = NULL; +} + + +/* {{{ proto object domxml_xslt_process(int xsldoc_handle, int xmldoc_handle, [array xslt_parameters]) + Perform an XSLT transformation */ +PHP_FUNCTION(domxml_xslt_process) +{ +/* TODO: + - add functions for dealing with xsltStylesheet objects + - split this function: domxml_xslt_process will receive: + - a handle to the xsltStylesheet object + - a handle to the xmlDoc object + - an optional array of parameters + - memory deallocation +*/ + zval *rv, *idxsl, *idxml, *idvars = NULL; + xmlDocPtr xsldocp, xmldocp, docp; + char **params = NULL; + xsltStylesheetPtr xsltstp; + int ret, parsize; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oo|a", &idxsl, &idxml, &idvars) == FAILURE) { + return; + } + + DOMXML_GET_OBJ(xsldocp, idxsl, le_domxmldocp); + DOMXML_GET_OBJ(xmldocp, idxml, le_domxmldocp); + + xsltstp = xsltParseStylesheetDoc(xsldocp); + if (!xsltstp) { + RETURN_FALSE; + } + if (xsltstp->errors) { +/* xsltFreeStylesheet(xsltstp);*/ + RETURN_FALSE; + } + + if (idvars) + { + HashTable *parht = HASH_OF(idvars); + parsize = (2 * zend_hash_num_elements(parht) + 1) * sizeof(char *); + params = (char **)emalloc(parsize); + memset((char *)params, 0, parsize); + _php_libxslt_ht_char(parht, params); + } + + docp = xsltApplyStylesheet(xsltstp, xmldocp, (const char**)params); + +/* xsltFreeStylesheet(xsltstp); + efree(params);*/ + + if (!docp) { + RETURN_FALSE; + } + + DOMXML_RET_OBJ(rv, (xmlNodePtr) docp, &ret); + + add_property_resource(return_value, "doc", ret); + if(docp->name) + add_property_stringl(return_value, "name", (char *) docp->name, strlen(docp->name), 1); + if(docp->URL) + add_property_stringl(return_value, "url", (char *) docp->name, strlen(docp->name), 1); +/* add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1);*/ + if(docp->version) + add_property_stringl(return_value, "version", (char *) docp->version, strlen(docp->version), 1); + if(docp->encoding) + add_property_stringl(return_value, "encoding", (char *) docp->encoding, strlen(docp->encoding), 1); + add_property_long(return_value, "standalone", docp->standalone); + add_property_long(return_value, "type", docp->type); + add_property_long(return_value, "compression", docp->compression); + add_property_long(return_value, "charset", docp->charset); + zend_list_addref(ret); +} +/* }}} */ + +/* {{{ proto string domxslt_version(void) + Get XSLT library version */ +PHP_FUNCTION(domxml_xslt_version) +{ + RETURN_STRING(LIBXSLT_DOTTED_VERSION, 1); +} +/* }}} */ +#endif /* HAVE_DOMXSLT */ + #endif /* HAVE_DOMXML */ /* diff --git a/ext/domxml/php_domxml.h b/ext/domxml/php_domxml.h index 9fdf1d174e..2a165ea2bd 100644 --- a/ext/domxml/php_domxml.h +++ b/ext/domxml/php_domxml.h @@ -23,12 +23,22 @@ #if HAVE_DOMXML #include +#include +#if defined(LIBXML_HTML_ENABLED) +#include +#include +#endif #if defined(LIBXML_XPATH_ENABLED) #include #endif #if defined(LIBXML_XPTR_ENABLED) #include #endif +#if HAVE_DOMXSLT +#include +#include +#include +#endif extern zend_module_entry domxml_module_entry; #define domxml_module_ptr &domxml_module_entry @@ -40,6 +50,10 @@ PHP_MINFO_FUNCTION(domxml); PHP_FUNCTION(domxml_version); PHP_FUNCTION(xmldoc); PHP_FUNCTION(xmldocfile); +#if defined(LIBXML_HTML_ENABLED) +PHP_FUNCTION(htmldoc); +PHP_FUNCTION(htmldocfile); +#endif PHP_FUNCTION(xmltree); PHP_FUNCTION(domxml_new_xmldoc); @@ -58,6 +72,9 @@ PHP_FUNCTION(domxml_doc_imported_node); PHP_FUNCTION(domxml_add_root); PHP_FUNCTION(domxml_intdtd); PHP_FUNCTION(domxml_dumpmem); +#if defined(LIBXML_HTML_ENABLED) +PHP_FUNCTION(domxml_htmldumpmem); +#endif /* Class DocumentType methods */ PHP_FUNCTION(domxml_doctype_name); @@ -142,6 +159,12 @@ PHP_FUNCTION(xptr_eval); #endif PHP_FUNCTION(domxml_test); +/* DOMXSLT functions */ +#if HAVE_DOMXSLT +PHP_FUNCTION(domxml_xslt_version); +PHP_FUNCTION(domxml_xslt_process); +#endif + #else #define domxml_module_ptr NULL #endif /* HAVE_DOMXML */