mirror of
https://github.com/php/php-src.git
synced 2024-11-29 21:04:10 +08:00
- 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().
This commit is contained in:
parent
f8a6ab9ae7
commit
415d5cbb75
@ -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 <libxslt/xsltconfig.h>
|
||||
#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=<DIR>)
|
||||
fi
|
||||
|
||||
AC_DEFINE(HAVE_DOMXSLT,1,[ ])
|
||||
PHP_SUBST(DOMXML_SHARED_LIBADD)
|
||||
fi
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -23,12 +23,22 @@
|
||||
|
||||
#if HAVE_DOMXML
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#if defined(LIBXML_HTML_ENABLED)
|
||||
#include <libxml/HTMLparser.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#endif
|
||||
#if defined(LIBXML_XPATH_ENABLED)
|
||||
#include <libxml/xpath.h>
|
||||
#endif
|
||||
#if defined(LIBXML_XPTR_ENABLED)
|
||||
#include <libxml/xpointer.h>
|
||||
#endif
|
||||
#if HAVE_DOMXSLT
|
||||
#include <libxslt/xsltInternals.h>
|
||||
#include <libxslt/xsltutils.h>
|
||||
#include <libxslt/transform.h>
|
||||
#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 */
|
||||
|
Loading…
Reference in New Issue
Block a user