summaryrefslogtreecommitdiff
path: root/ext/dom
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dom')
-rw-r--r--ext/dom/CREDITS2
-rw-r--r--ext/dom/TODO4
-rw-r--r--ext/dom/attr.c289
-rw-r--r--ext/dom/cdatasection.c94
-rw-r--r--ext/dom/characterdata.c426
-rw-r--r--ext/dom/comment.c94
-rw-r--r--ext/dom/config.m438
-rw-r--r--ext/dom/config.w3227
-rw-r--r--ext/dom/document.c2422
-rw-r--r--ext/dom/documentfragment.c168
-rw-r--r--ext/dom/documenttype.c235
-rw-r--r--ext/dom/dom.dsp250
-rw-r--r--ext/dom/dom_ce.h66
-rw-r--r--ext/dom/dom_fe.h280
-rw-r--r--ext/dom/dom_iterators.c351
-rw-r--r--ext/dom/dom_properties.h171
-rw-r--r--ext/dom/domconfiguration.c103
-rw-r--r--ext/dom/domerror.c139
-rw-r--r--ext/dom/domerrorhandler.c71
-rw-r--r--ext/dom/domexception.c125
-rw-r--r--ext/dom/domimplementation.c268
-rw-r--r--ext/dom/domimplementationlist.c85
-rw-r--r--ext/dom/domimplementationsource.c87
-rw-r--r--ext/dom/domlocator.c125
-rw-r--r--ext/dom/domstringlist.c85
-rw-r--r--ext/dom/element.c1254
-rw-r--r--ext/dom/entity.c195
-rw-r--r--ext/dom/entityreference.c100
-rw-r--r--ext/dom/examples/dom1.inc43
-rw-r--r--ext/dom/examples/dom1.php94
-rw-r--r--ext/dom/examples/note-invalid.xml9
-rw-r--r--ext/dom/examples/note.dtd6
-rw-r--r--ext/dom/examples/note.php19
-rw-r--r--ext/dom/examples/note.xml8
-rw-r--r--ext/dom/examples/relaxNG.php11
-rw-r--r--ext/dom/examples/relaxNG.rng11
-rw-r--r--ext/dom/examples/relaxNG.xml1
-rw-r--r--ext/dom/examples/relaxNG2.rng23
-rw-r--r--ext/dom/examples/relaxNG3.rng8
-rw-r--r--ext/dom/examples/shipping.php11
-rw-r--r--ext/dom/examples/shipping.xml21
-rw-r--r--ext/dom/examples/shipping.xsd36
-rw-r--r--ext/dom/namednodemap.c338
-rw-r--r--ext/dom/namelist.c96
-rw-r--r--ext/dom/node.c1990
-rw-r--r--ext/dom/nodelist.c184
-rw-r--r--ext/dom/notation.c110
-rw-r--r--ext/dom/php_dom.c1682
-rw-r--r--ext/dom/php_dom.h165
-rw-r--r--ext/dom/processinginstruction.c188
-rw-r--r--ext/dom/string_extend.c86
-rw-r--r--ext/dom/tests/DOMAttr_construct_error_001.phpt17
-rw-r--r--ext/dom/tests/DOMAttr_name_basic_001.phpt14
-rw-r--r--ext/dom/tests/DOMAttr_ownerElement_error_001.phpt23
-rw-r--r--ext/dom/tests/DOMAttr_value_basic_001.phpt16
-rw-r--r--ext/dom/tests/DOMAttr_value_basic_002.phpt15
-rw-r--r--ext/dom/tests/DOMCDATASection_construct_error_001.phpt21
-rw-r--r--ext/dom/tests/DOMCharacterData_appendData_basic.phpt37
-rw-r--r--ext/dom/tests/DOMCharacterData_appendData_error_001.phpt19
-rw-r--r--ext/dom/tests/DOMCharacterData_data_basic_002.phpt28
-rw-r--r--ext/dom/tests/DOMCharacterData_data_error_002.phpt14
-rw-r--r--ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt20
-rw-r--r--ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt19
-rw-r--r--ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt23
-rw-r--r--ext/dom/tests/DOMCharacterData_insertData_error_001.phpt19
-rw-r--r--ext/dom/tests/DOMCharacterData_length_error_001.phpt17
-rw-r--r--ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt19
-rw-r--r--ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt21
-rw-r--r--ext/dom/tests/DOMComment_appendData_basic.phpt21
-rw-r--r--ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt37
-rw-r--r--ext/dom/tests/DOMComment_construct_basic_001.phpt19
-rw-r--r--ext/dom/tests/DOMComment_construct_error_001.phpt17
-rw-r--r--ext/dom/tests/DOMComment_insertData_basic.phpt21
-rw-r--r--ext/dom/tests/DOMComment_insertData_error1.phpt24
-rw-r--r--ext/dom/tests/DOMComment_insertData_error2.phpt24
-rw-r--r--ext/dom/tests/DOMComment_replaceData_basic.phpt29
-rw-r--r--ext/dom/tests/DOMComment_replaceData_error1.phpt24
-rw-r--r--ext/dom/tests/DOMComment_replaceData_error2.phpt24
-rw-r--r--ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt22
-rw-r--r--ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt19
-rw-r--r--ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt19
-rw-r--r--ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt23
-rw-r--r--ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt16
-rw-r--r--ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt17
-rw-r--r--ext/dom/tests/DOMDocumentType_basic_001.phpt48
-rw-r--r--ext/dom/tests/DOMDocumentType_entities_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentType_name_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentType_notations_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt19
-rw-r--r--ext/dom/tests/DOMDocumentType_publicId_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt19
-rw-r--r--ext/dom/tests/DOMDocumentType_systemId_error_001.phpt14
-rw-r--r--ext/dom/tests/DOMDocument_config_basic.phpt26
-rw-r--r--ext/dom/tests/DOMDocument_createAttribute_basic.phpt26
-rw-r--r--ext/dom/tests/DOMDocument_createAttribute_error.phpt27
-rw-r--r--ext/dom/tests/DOMDocument_createAttribute_error1.phpt29
-rw-r--r--ext/dom/tests/DOMDocument_createAttribute_variation.phpt14
-rw-r--r--ext/dom/tests/DOMDocument_createEntityReference_basic.phpt19
-rw-r--r--ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt30
-rw-r--r--ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt31
-rw-r--r--ext/dom/tests/DOMDocument_documentURI_basic.phpt39
-rw-r--r--ext/dom/tests/DOMDocument_encoding_basic.phpt52
-rw-r--r--ext/dom/tests/DOMDocument_implementationRead_basic.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_loadHTML_basic.phpt18
-rw-r--r--ext/dom/tests/DOMDocument_loadHTML_error1.phpt15
-rw-r--r--ext/dom/tests/DOMDocument_loadHTML_error2.phpt15
-rw-r--r--ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt23
-rw-r--r--ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt40
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt39
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt41
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt39
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt24
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng11
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt26
-rw-r--r--ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt31
-rw-r--r--ext/dom/tests/DOMDocument_resolveExternals_basic.phpt49
-rw-r--r--ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt29
-rw-r--r--ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt24
-rw-r--r--ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt15
-rw-r--r--ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt33
-rw-r--r--ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt25
-rw-r--r--ext/dom/tests/DOMDocument_saveHTML_basic.phpt24
-rw-r--r--ext/dom/tests/DOMDocument_saveHTML_error2.phpt15
-rw-r--r--ext/dom/tests/DOMDocument_saveHTML_variant1.phpt24
-rw-r--r--ext/dom/tests/DOMDocument_saveHTML_variant2.phpt26
-rw-r--r--ext/dom/tests/DOMDocument_save_basic.phpt33
-rw-r--r--ext/dom/tests/DOMDocument_savexml_basic.phpt39
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt29
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt23
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_basic.phpt20
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_error1.phpt29
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_error2.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_error3.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_error4.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_error5.phpt25
-rw-r--r--ext/dom/tests/DOMDocument_standalone_basic.phpt48
-rw-r--r--ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt59
-rw-r--r--ext/dom/tests/DOMDocument_validate_basic.phpt31
-rw-r--r--ext/dom/tests/DOMDocument_validate_error1.phpt16
-rw-r--r--ext/dom/tests/DOMDocument_validate_error2.phpt15
-rw-r--r--ext/dom/tests/DOMDocument_validate_external_dtd.phpt19
-rw-r--r--ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt38
-rw-r--r--ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt46
-rw-r--r--ext/dom/tests/DOMElement_hasAttributes_basic.phpt49
-rw-r--r--ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt18
-rw-r--r--ext/dom/tests/DOMImplementation_createDocument_basic.phpt14
-rw-r--r--ext/dom/tests/DOMImplementation_hasFeature_basic.phpt15
-rw-r--r--ext/dom/tests/DOMNode_C14NFile_basic.phpt38
-rw-r--r--ext/dom/tests/DOMNode_C14N_basic.phpt29
-rw-r--r--ext/dom/tests/DOMNode_cloneNode_basic.phpt106
-rw-r--r--ext/dom/tests/DOMNode_getLineNo_basic.phpt19
-rw-r--r--ext/dom/tests/DOMNode_getNodePath_basic.phpt19
-rw-r--r--ext/dom/tests/DOMNode_hasChildNodes.phpt49
-rw-r--r--ext/dom/tests/DOMNode_hasChildNodes_basic.phpt43
-rw-r--r--ext/dom/tests/DOMNode_insertBefore.phpt34
-rw-r--r--ext/dom/tests/DOMNode_insertBefore_error1.phpt24
-rw-r--r--ext/dom/tests/DOMNode_issamenode_basic.phpt37
-rw-r--r--ext/dom/tests/DOMNode_normalize_basic.phpt64
-rw-r--r--ext/dom/tests/DOMNode_removeChild_basic.phpt106
-rw-r--r--ext/dom/tests/DOMNode_replaceChild_basic.phpt44
-rw-r--r--ext/dom/tests/DOMText_appendData_basic.phpt40
-rwxr-xr-xext/dom/tests/book-non-conforming-schema.xsd17
-rwxr-xr-xext/dom/tests/book-not-a-schema.xsd1
-rw-r--r--ext/dom/tests/book.xml11
-rw-r--r--ext/dom/tests/book.xml.gzbin0 -> 119 bytes
-rwxr-xr-xext/dom/tests/book.xsd17
-rw-r--r--ext/dom/tests/bug28721.phpt485
-rw-r--r--ext/dom/tests/bug28817.phpt38
-rw-r--r--ext/dom/tests/bug32615.phpt84
-rw-r--r--ext/dom/tests/bug34276.phpt43
-rw-r--r--ext/dom/tests/bug35342.phpt20
-rw-r--r--ext/dom/tests/bug35673.phpt20
-rw-r--r--ext/dom/tests/bug36756.phpt35
-rw-r--r--ext/dom/tests/bug37277.phpt25
-rw-r--r--ext/dom/tests/bug37456.phpt22
-rw-r--r--ext/dom/tests/bug38438.phpt13
-rw-r--r--ext/dom/tests/bug38474.phpt46
-rw-r--r--ext/dom/tests/bug38850.phpt22
-rw-r--r--ext/dom/tests/bug38949.phpt27
-rw-r--r--ext/dom/tests/bug40836.phpt29
-rw-r--r--ext/dom/tests/bug41257.phpt31
-rw-r--r--ext/dom/tests/bug41374.phpt32
-rw-r--r--ext/dom/tests/bug42082.phpt31
-rw-r--r--ext/dom/tests/bug43364.phpt42
-rw-r--r--ext/dom/tests/bug44648.phpt45
-rw-r--r--ext/dom/tests/bug45251.phpt30
-rw-r--r--ext/dom/tests/bug46185.phpt23
-rw-r--r--ext/dom/tests/bug46335.phpt35
-rw-r--r--ext/dom/tests/bug46849.phpt16
-rw-r--r--ext/dom/tests/bug47430.phpt30
-rw-r--r--ext/dom/tests/bug47848.phpt25
-rw-r--r--ext/dom/tests/bug47849.phpt22
-rw-r--r--ext/dom/tests/bug49463.phpt17
-rw-r--r--ext/dom/tests/bug49490.phpt17
-rw-r--r--ext/dom/tests/bug50661.phpt16
-rw-r--r--ext/dom/tests/bug52656.phpt14
-rw-r--r--ext/dom/tests/bug54601.phpt29
-rw-r--r--ext/dom/tests/canonicalization.phpt102
-rw-r--r--ext/dom/tests/dom.ent8
-rw-r--r--ext/dom/tests/dom.xml8
-rw-r--r--ext/dom/tests/dom001.phpt275
-rw-r--r--ext/dom/tests/dom002.phpt57
-rw-r--r--ext/dom/tests/dom003.phpt69
-rw-r--r--ext/dom/tests/dom004.phpt25
-rw-r--r--ext/dom/tests/dom005.phpt33
-rw-r--r--ext/dom/tests/dom006.phpt40
-rw-r--r--ext/dom/tests/dom007.phpt111
-rw-r--r--ext/dom/tests/dom_comment_basic.phpt43
-rw-r--r--ext/dom/tests/dom_comment_variation.phpt32
-rw-r--r--ext/dom/tests/dom_create_element.phpt394
-rw-r--r--ext/dom/tests/dom_import_simplexml.phpt27
-rw-r--r--ext/dom/tests/dom_set_attr_node.phpt74
-rw-r--r--ext/dom/tests/dom_test.inc47
-rw-r--r--ext/dom/tests/dom_xinclude.phpt42
-rw-r--r--ext/dom/tests/domattributes.phpt43
-rw-r--r--ext/dom/tests/domchardata.phpt76
-rw-r--r--ext/dom/tests/domdocument_createcomment_error_001.phpt16
-rw-r--r--ext/dom/tests/domdocument_createentityreference_001.phpt18
-rw-r--r--ext/dom/tests/domdocument_createentityreference_002.phpt17
-rw-r--r--ext/dom/tests/domelement.phpt114
-rw-r--r--ext/dom/tests/domobject_debug_handler.phpt59
-rw-r--r--ext/dom/tests/domxpath.phpt58
-rw-r--r--ext/dom/tests/note.dtd6
-rw-r--r--ext/dom/tests/note.xml8
-rw-r--r--ext/dom/tests/nsdoc.xml4
-rw-r--r--ext/dom/tests/regsiter_node_class.phpt40
-rw-r--r--ext/dom/tests/skipif.inc1
-rw-r--r--ext/dom/tests/test.html9
-rw-r--r--ext/dom/tests/xinclude.xml4
-rw-r--r--ext/dom/text.c245
-rw-r--r--ext/dom/typeinfo.c83
-rw-r--r--ext/dom/userdatahandler.c66
-rw-r--r--ext/dom/xml_common.h106
-rw-r--r--ext/dom/xpath.c602
241 files changed, 20229 insertions, 0 deletions
diff --git a/ext/dom/CREDITS b/ext/dom/CREDITS
new file mode 100644
index 0000000..b78e376
--- /dev/null
+++ b/ext/dom/CREDITS
@@ -0,0 +1,2 @@
+DOM
+Christian Stocker, Rob Richards, Marcus Boerger
diff --git a/ext/dom/TODO b/ext/dom/TODO
new file mode 100644
index 0000000..52afb18
--- /dev/null
+++ b/ext/dom/TODO
@@ -0,0 +1,4 @@
+For 5.1
+1) enhance XPath functionality
+2) look at auto encoding support for in/output
+3) What DOM object types are really needed (i.e. not currently using DOMString)
diff --git a/ext/dom/attr.c b/ext/dom/attr.c
new file mode 100644
index 0000000..d45ca88
--- /dev/null
+++ b/ext/dom/attr.c
@@ -0,0 +1,289 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+
+#if HAVE_LIBXML && HAVE_DOM
+
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_attr_is_id, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_attr_construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMAttr extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-637646024
+* Since:
+*/
+
+const zend_function_entry php_dom_attr_class_functions[] = {
+ PHP_FALIAS(isId, dom_attr_is_id, arginfo_dom_attr_is_id)
+ PHP_ME(domattr, __construct, arginfo_dom_attr_construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* {{{ proto void DOMAttr::__construct(string name, [string value]); */
+PHP_METHOD(domattr, __construct)
+{
+
+ zval *id;
+ xmlAttrPtr nodep = NULL;
+ xmlNodePtr oldnode = NULL;
+ dom_object *intern;
+ char *name, *value = NULL;
+ int name_len, value_len, name_valid;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_attr_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ name_valid = xmlValidateName((xmlChar *) name, 0);
+ if (name_valid != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ nodep = xmlNewProp(NULL, (xmlChar *) name, value);
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC);
+ }
+}
+
+/* }}} end DOMAttr::__construct */
+
+/* {{{ name string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1112119403
+Since:
+*/
+int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlAttrPtr attrp;
+
+ attrp = (xmlAttrPtr) dom_object_get_node(obj);
+
+ if (attrp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, (char *) (attrp->name), 1);
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ specified boolean
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-862529273
+Since:
+*/
+int dom_attr_specified_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ /* TODO */
+ ALLOC_ZVAL(*retval);
+ ZVAL_TRUE(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ value string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-221662474
+Since:
+*/
+int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlAttrPtr attrp;
+ xmlChar *content;
+
+ attrp = (xmlAttrPtr) dom_object_get_node(obj);
+
+ if (attrp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+
+ if ((content = xmlNodeGetContent((xmlNodePtr) attrp)) != NULL) {
+ ZVAL_STRING(*retval, content, 1);
+ xmlFree(content);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+
+}
+
+int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlAttrPtr attrp;
+
+ attrp = (xmlAttrPtr) dom_object_get_node(obj);
+
+ if (attrp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (attrp->children) {
+ node_list_unlink(attrp->children TSRMLS_CC);
+ }
+
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+
+ xmlNodeSetContentLen((xmlNodePtr) attrp, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ ownerElement DOMElement
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-ownerElement
+Since: DOM Level 2
+*/
+int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr nodep, nodeparent;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ nodeparent = nodep->parent;
+ if (!nodeparent) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+
+}
+
+/* }}} */
+
+/* {{{ schemaTypeInfo DOMTypeInfo
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-schemaTypeInfo
+Since: DOM Level 3
+*/
+int dom_attr_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented");
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto boolean dom_attr_is_id();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Attr-isId
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_attr_is_id)
+{
+ zval *id;
+ dom_object *intern;
+ xmlAttrPtr attrp;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_attr_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(attrp, id, xmlAttrPtr, intern);
+
+ if (attrp->atype == XML_ATTRIBUTE_ID) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_attr_is_id */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c
new file mode 100644
index 0000000..dc8a3f1
--- /dev/null
+++ b/ext/dom/cdatasection.c
@@ -0,0 +1,94 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_cdatasection_construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMCdataSection extends DOMText
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-667469212
+* Since:
+*/
+
+const zend_function_entry php_dom_cdatasection_class_functions[] = {
+ PHP_ME(domcdatasection, __construct, arginfo_dom_cdatasection_construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* {{{ proto void DOMCdataSection::__construct(string value); */
+PHP_METHOD(domcdatasection, __construct)
+{
+
+ zval *id;
+ xmlNodePtr nodep = NULL, oldnode = NULL;
+ dom_object *intern;
+ char *value = NULL;
+ int value_len;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_cdatasection_class_entry, &value, &value_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ nodep = xmlNewCDataBlock(NULL, (xmlChar *) value, value_len);
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMCdataSection::__construct */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c
new file mode 100644
index 0000000..3b1f9b1
--- /dev/null
+++ b/ext/dom/characterdata.c
@@ -0,0 +1,426 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_substring_data, 0, 0, 2)
+ ZEND_ARG_INFO(0, offset)
+ ZEND_ARG_INFO(0, count)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_append_data, 0, 0, 1)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_insert_data, 0, 0, 2)
+ ZEND_ARG_INFO(0, offset)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_delete_data, 0, 0, 2)
+ ZEND_ARG_INFO(0, offset)
+ ZEND_ARG_INFO(0, count)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_characterdata_replace_data, 0, 0, 3)
+ ZEND_ARG_INFO(0, offset)
+ ZEND_ARG_INFO(0, count)
+ ZEND_ARG_INFO(0, arg)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMCharacterData extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-FF21A306
+* Since:
+*/
+
+const zend_function_entry php_dom_characterdata_class_functions[] = {
+ PHP_FALIAS(substringData, dom_characterdata_substring_data, arginfo_dom_characterdata_substring_data)
+ PHP_FALIAS(appendData, dom_characterdata_append_data, arginfo_dom_characterdata_append_data)
+ PHP_FALIAS(insertData, dom_characterdata_insert_data, arginfo_dom_characterdata_insert_data)
+ PHP_FALIAS(deleteData, dom_characterdata_delete_data, arginfo_dom_characterdata_delete_data)
+ PHP_FALIAS(replaceData, dom_characterdata_replace_data, arginfo_dom_characterdata_replace_data)
+ PHP_FE_END
+};
+
+/* {{{ data string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-72AB8359
+Since:
+*/
+int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr nodep;
+ xmlChar *content;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if ((content = xmlNodeGetContent(nodep)) != NULL) {
+ ZVAL_STRING(*retval, content, 1);
+ xmlFree(content);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlNode *nodep;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+
+ xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ length long
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7D61178C
+Since:
+*/
+int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr nodep;
+ xmlChar *content;
+ long length = 0;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ content = xmlNodeGetContent(nodep);
+
+ if (content) {
+ length = xmlUTF8Strlen(content);
+ xmlFree(content);
+ }
+
+ ZVAL_LONG(*retval, length);
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto string dom_characterdata_substring_data(int offset, int count);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6531BCCF
+Since:
+*/
+PHP_FUNCTION(dom_characterdata_substring_data)
+{
+ zval *id;
+ xmlChar *cur;
+ xmlChar *substring;
+ xmlNodePtr node;
+ long offset, count;
+ int length;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(node, id, xmlNodePtr, intern);
+
+ cur = xmlNodeGetContent(node);
+ if (cur == NULL) {
+ RETURN_FALSE;
+ }
+
+ length = xmlUTF8Strlen(cur);
+
+ if (offset < 0 || count < 0 || offset > length) {
+ xmlFree(cur);
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if ((offset + count) > length) {
+ count = length - offset;
+ }
+
+ substring = xmlUTF8Strsub(cur, offset, count);
+ xmlFree(cur);
+
+ if (substring) {
+ RETVAL_STRING(substring, 1);
+ xmlFree(substring);
+ } else {
+ RETVAL_EMPTY_STRING();
+ }
+}
+/* }}} end dom_characterdata_substring_data */
+
+/* {{{ proto void dom_characterdata_append_data(string arg);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-32791A2F
+Since:
+*/
+PHP_FUNCTION(dom_characterdata_append_data)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+ char *arg;
+ int arg_len;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_characterdata_class_entry, &arg, &arg_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+#if LIBXML_VERSION < 20627
+/* Implement logic from libxml xmlTextConcat to add suport for comments and PI */
+ if ((nodep->content == (xmlChar *) &(nodep->properties)) ||
+ ((nodep->doc != NULL) && (nodep->doc->dict != NULL) &&
+ xmlDictOwns(nodep->doc->dict, nodep->content))) {
+ nodep->content = xmlStrncatNew(nodep->content, arg, arg_len);
+ } else {
+ nodep->content = xmlStrncat(nodep->content, arg, arg_len);
+ }
+ nodep->properties = NULL;
+#else
+ xmlTextConcat(nodep, arg, arg_len);
+#endif
+ RETURN_TRUE;
+}
+/* }}} end dom_characterdata_append_data */
+
+/* {{{ proto void dom_characterdata_insert_data(int offset, string arg);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3EDB695F
+Since:
+*/
+PHP_FUNCTION(dom_characterdata_insert_data)
+{
+ zval *id;
+ xmlChar *cur, *first, *second;
+ xmlNodePtr node;
+ char *arg;
+ long offset;
+ int length, arg_len;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ols", &id, dom_characterdata_class_entry, &offset, &arg, &arg_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(node, id, xmlNodePtr, intern);
+
+ cur = xmlNodeGetContent(node);
+ if (cur == NULL) {
+ RETURN_FALSE;
+ }
+
+ length = xmlUTF8Strlen(cur);
+
+ if (offset < 0 || offset > length) {
+ xmlFree(cur);
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ first = xmlUTF8Strndup(cur, offset);
+ second = xmlUTF8Strsub(cur, offset, length - offset);
+ xmlFree(cur);
+
+ xmlNodeSetContent(node, first);
+ xmlNodeAddContent(node, arg);
+ xmlNodeAddContent(node, second);
+
+ xmlFree(first);
+ xmlFree(second);
+
+ RETURN_TRUE;
+}
+/* }}} end dom_characterdata_insert_data */
+
+/* {{{ proto void dom_characterdata_delete_data(int offset, int count);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-7C603781
+Since:
+*/
+PHP_FUNCTION(dom_characterdata_delete_data)
+{
+ zval *id;
+ xmlChar *cur, *substring, *second;
+ xmlNodePtr node;
+ long offset, count;
+ int length;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &id, dom_characterdata_class_entry, &offset, &count) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(node, id, xmlNodePtr, intern);
+
+ cur = xmlNodeGetContent(node);
+ if (cur == NULL) {
+ RETURN_FALSE;
+ }
+
+ length = xmlUTF8Strlen(cur);
+
+ if (offset < 0 || count < 0 || offset > length) {
+ xmlFree(cur);
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (offset > 0) {
+ substring = xmlUTF8Strsub(cur, 0, offset);
+ } else {
+ substring = NULL;
+ }
+
+ if ((offset + count) > length) {
+ count = length - offset;
+ }
+
+ second = xmlUTF8Strsub(cur, offset + count, length - offset);
+ substring = xmlStrcat(substring, second);
+
+ xmlNodeSetContent(node, substring);
+
+ xmlFree(cur);
+ xmlFree(second);
+ xmlFree(substring);
+
+ RETURN_TRUE;
+}
+/* }}} end dom_characterdata_delete_data */
+
+/* {{{ proto void dom_characterdata_replace_data(int offset, int count, string arg);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-E5CBA7FB
+Since:
+*/
+PHP_FUNCTION(dom_characterdata_replace_data)
+{
+ zval *id;
+ xmlChar *cur, *substring, *second = NULL;
+ xmlNodePtr node;
+ char *arg;
+ long offset, count;
+ int length, arg_len;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olls", &id, dom_characterdata_class_entry, &offset, &count, &arg, &arg_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(node, id, xmlNodePtr, intern);
+
+ cur = xmlNodeGetContent(node);
+ if (cur == NULL) {
+ RETURN_FALSE;
+ }
+
+ length = xmlUTF8Strlen(cur);
+
+ if (offset < 0 || count < 0 || offset > length) {
+ xmlFree(cur);
+ php_dom_throw_error(INDEX_SIZE_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (offset > 0) {
+ substring = xmlUTF8Strsub(cur, 0, offset);
+ } else {
+ substring = NULL;
+ }
+
+ if ((offset + count) > length) {
+ count = length - offset;
+ }
+
+ if (offset < length) {
+ second = xmlUTF8Strsub(cur, offset + count, length - offset);
+ }
+
+ substring = xmlStrcat(substring, arg);
+ substring = xmlStrcat(substring, second);
+
+ xmlNodeSetContent(node, substring);
+
+ xmlFree(cur);
+ if (second) {
+ xmlFree(second);
+ }
+ xmlFree(substring);
+
+ RETURN_TRUE;
+}
+/* }}} end dom_characterdata_replace_data */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/comment.c b/ext/dom/comment.c
new file mode 100644
index 0000000..017c2ba
--- /dev/null
+++ b/ext/dom/comment.c
@@ -0,0 +1,94 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_comment_construct, 0, 0, 0)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMComment extends DOMCharacterData
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1728279322
+* Since:
+*/
+
+const zend_function_entry php_dom_comment_class_functions[] = {
+ PHP_ME(domcomment, __construct, arginfo_dom_comment_construct, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+/* {{{ proto void DOMComment::__construct([string value]); */
+PHP_METHOD(domcomment, __construct)
+{
+
+ zval *id;
+ xmlNodePtr nodep = NULL, oldnode = NULL;
+ dom_object *intern;
+ char *value = NULL;
+ int value_len;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_comment_class_entry, &value, &value_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ nodep = xmlNewComment((xmlChar *) value);
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)nodep, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMComment::__construct */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/config.m4 b/ext/dom/config.m4
new file mode 100644
index 0000000..7882483
--- /dev/null
+++ b/ext/dom/config.m4
@@ -0,0 +1,38 @@
+dnl
+dnl $Id$
+dnl
+
+PHP_ARG_ENABLE(dom, whether to enable DOM support,
+[ --disable-dom Disable DOM support], yes)
+
+if test -z "$PHP_LIBXML_DIR"; then
+ PHP_ARG_WITH(libxml-dir, libxml2 install dir,
+ [ --with-libxml-dir[=DIR] DOM: libxml2 install prefix], no, no)
+fi
+
+if test "$PHP_DOM" != "no"; then
+
+ if test "$PHP_LIBXML" = "no"; then
+ AC_MSG_ERROR([DOM extension requires LIBXML extension, add --enable-libxml])
+ fi
+
+ PHP_SETUP_LIBXML(DOM_SHARED_LIBADD, [
+ AC_DEFINE(HAVE_DOM,1,[ ])
+ PHP_NEW_EXTENSION(dom, [php_dom.c attr.c document.c domerrorhandler.c \
+ domstringlist.c domexception.c namelist.c \
+ processinginstruction.c cdatasection.c \
+ documentfragment.c domimplementation.c \
+ element.c node.c string_extend.c characterdata.c \
+ documenttype.c domimplementationlist.c entity.c \
+ nodelist.c text.c comment.c domconfiguration.c \
+ domimplementationsource.c entityreference.c \
+ notation.c xpath.c dom_iterators.c \
+ typeinfo.c domerror.c domlocator.c namednodemap.c userdatahandler.c],
+ $ext_shared)
+ PHP_SUBST(DOM_SHARED_LIBADD)
+ PHP_INSTALL_HEADERS([ext/dom/xml_common.h])
+ PHP_ADD_EXTENSION_DEP(dom, libxml)
+ ], [
+ AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.])
+ ])
+fi
diff --git a/ext/dom/config.w32 b/ext/dom/config.w32
new file mode 100644
index 0000000..cbe15af
--- /dev/null
+++ b/ext/dom/config.w32
@@ -0,0 +1,27 @@
+// $Id$
+// vim:ft=javascript
+
+ARG_WITH("dom", "DOM support", "yes");
+
+if (PHP_DOM == "yes") {
+ if (PHP_LIBXML == "yes" && ADD_EXTENSION_DEP('dom', 'libxml')) {
+ EXTENSION("dom", "php_dom.c attr.c document.c domerrorhandler.c \
+ domstringlist.c domexception.c namelist.c processinginstruction.c \
+ cdatasection.c documentfragment.c domimplementation.c element.c \
+ node.c string_extend.c characterdata.c documenttype.c \
+ domimplementationlist.c entity.c nodelist.c text.c comment.c \
+ domconfiguration.c domimplementationsource.c entityreference.c \
+ notation.c xpath.c dom_iterators.c typeinfo.c domerror.c \
+ domlocator.c namednodemap.c userdatahandler.c");
+
+ AC_DEFINE("HAVE_DOM", 1, "DOM support");
+
+ if (!PHP_DOM_SHARED) {
+ ADD_FLAG("CFLAGS_DOM", "/D LIBXML_STATIC ");
+ }
+ PHP_INSTALL_HEADERS("ext/dom", "xml_common.h");
+ } else {
+ WARNING("dom support can't be enabled, libxml is not enabled")
+ PHP_DOM = "no"
+ }
+}
diff --git a/ext/dom/document.c b/ext/dom/document.c
new file mode 100644
index 0000000..d17c7cb
--- /dev/null
+++ b/ext/dom/document.c
@@ -0,0 +1,2422 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+#include <libxml/SAX.h>
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
+#endif
+
+typedef struct _idsIterator idsIterator;
+struct _idsIterator {
+ xmlChar *elementId;
+ xmlNode *element;
+};
+
+#define DOM_LOAD_STRING 0
+#define DOM_LOAD_FILE 1
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element, 0, 0, 1)
+ ZEND_ARG_INFO(0, tagName)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_document_fragment, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_text_node, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_comment, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_cdatasection, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_processing_instruction, 0, 0, 2)
+ ZEND_ARG_INFO(0, target)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_entity_reference, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name, 0, 0, 1)
+ ZEND_ARG_INFO(0, tagName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_import_node, 0, 0, 2)
+ ZEND_ARG_OBJ_INFO(0, importedNode, DOMNode, 0)
+ ZEND_ARG_INFO(0, deep)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_element_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_create_attribute_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_elements_by_tag_name_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_get_element_by_id, 0, 0, 1)
+ ZEND_ARG_INFO(0, elementId)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_adopt_node, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, source, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_normalize_document, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_rename_node, 0, 0, 3)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 0)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_load, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_save, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadxml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savexml, 0, 0, 0)
+ ZEND_ARG_OBJ_INFO(0, node, DOMNode, 1)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_construct, 0, 0, 0)
+ ZEND_ARG_INFO(0, version)
+ ZEND_ARG_INFO(0, encoding)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_validate, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_xinclude, 0, 0, 0)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_loadhtmlfile, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtml, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_savehtmlfile, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_schema_validate_xml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_relaxNG_validate_xml, 0, 0, 1)
+ ZEND_ARG_INFO(0, source)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_document_registernodeclass, 0, 0, 2)
+ ZEND_ARG_INFO(0, baseClass)
+ ZEND_ARG_INFO(0, extendedClass)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMDocument extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-i-Document
+* Since:
+*/
+
+const zend_function_entry php_dom_document_class_functions[] = { /* {{{ */
+ PHP_FALIAS(createElement, dom_document_create_element, arginfo_dom_document_create_element)
+ PHP_FALIAS(createDocumentFragment, dom_document_create_document_fragment, arginfo_dom_document_create_document_fragment)
+ PHP_FALIAS(createTextNode, dom_document_create_text_node, arginfo_dom_document_create_text_node)
+ PHP_FALIAS(createComment, dom_document_create_comment, arginfo_dom_document_create_comment)
+ PHP_FALIAS(createCDATASection, dom_document_create_cdatasection, arginfo_dom_document_create_cdatasection)
+ PHP_FALIAS(createProcessingInstruction, dom_document_create_processing_instruction, arginfo_dom_document_create_processing_instruction)
+ PHP_FALIAS(createAttribute, dom_document_create_attribute, arginfo_dom_document_create_attribute)
+ PHP_FALIAS(createEntityReference, dom_document_create_entity_reference, arginfo_dom_document_create_entity_reference)
+ PHP_FALIAS(getElementsByTagName, dom_document_get_elements_by_tag_name, arginfo_dom_document_get_elements_by_tag_name)
+ PHP_FALIAS(importNode, dom_document_import_node, arginfo_dom_document_import_node)
+ PHP_FALIAS(createElementNS, dom_document_create_element_ns, arginfo_dom_document_create_element_ns)
+ PHP_FALIAS(createAttributeNS, dom_document_create_attribute_ns, arginfo_dom_document_create_attribute_ns)
+ PHP_FALIAS(getElementsByTagNameNS, dom_document_get_elements_by_tag_name_ns, arginfo_dom_document_get_elements_by_tag_name_ns)
+ PHP_FALIAS(getElementById, dom_document_get_element_by_id, arginfo_dom_document_get_element_by_id)
+ PHP_FALIAS(adoptNode, dom_document_adopt_node, arginfo_dom_document_adopt_node)
+ PHP_FALIAS(normalizeDocument, dom_document_normalize_document, arginfo_dom_document_normalize_document)
+ PHP_FALIAS(renameNode, dom_document_rename_node, arginfo_dom_document_rename_node)
+ PHP_ME(domdocument, load, arginfo_dom_document_load, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FALIAS(save, dom_document_save, arginfo_dom_document_save)
+ PHP_ME(domdocument, loadXML, arginfo_dom_document_loadxml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FALIAS(saveXML, dom_document_savexml, arginfo_dom_document_savexml)
+ PHP_ME(domdocument, __construct, arginfo_dom_document_construct, ZEND_ACC_PUBLIC)
+ PHP_FALIAS(validate, dom_document_validate, arginfo_dom_document_validate)
+ PHP_FALIAS(xinclude, dom_document_xinclude, arginfo_dom_document_xinclude)
+#if defined(LIBXML_HTML_ENABLED)
+ PHP_ME(domdocument, loadHTML, arginfo_dom_document_loadhtml, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_ME(domdocument, loadHTMLFile, arginfo_dom_document_loadhtmlfile, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FALIAS(saveHTML, dom_document_save_html, arginfo_dom_document_savehtml)
+ PHP_FALIAS(saveHTMLFile, dom_document_save_html_file, arginfo_dom_document_savehtmlfile)
+#endif /* defined(LIBXML_HTML_ENABLED) */
+#if defined(LIBXML_SCHEMAS_ENABLED)
+ PHP_FALIAS(schemaValidate, dom_document_schema_validate_file, arginfo_dom_document_schema_validate_file)
+ PHP_FALIAS(schemaValidateSource, dom_document_schema_validate_xml, arginfo_dom_document_schema_validate_xml)
+ PHP_FALIAS(relaxNGValidate, dom_document_relaxNG_validate_file, arginfo_dom_document_relaxNG_validate_file)
+ PHP_FALIAS(relaxNGValidateSource, dom_document_relaxNG_validate_xml, arginfo_dom_document_relaxNG_validate_xml)
+#endif
+ PHP_ME(domdocument, registerNodeClass, arginfo_dom_document_registernodeclass, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ docType DOMDocumentType
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-B63ED1A31
+Since:
+*/
+int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ xmlDtdPtr dtdptr;
+ int ret;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ dtdptr = xmlGetIntSubset(docp);
+ if (!dtdptr) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object((xmlNodePtr) dtdptr, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+
+}
+
+/* }}} */
+
+/* {{{ implementation DOMImplementation
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1B793EBA
+Since:
+*/
+int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ php_dom_create_implementation(retval TSRMLS_CC);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ documentElement DOMElement
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-87CD092
+Since:
+*/
+int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ xmlNode *root;
+ int ret;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ root = xmlDocGetRootElement(docp);
+ if (!root) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(root, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ encoding string
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-encoding
+Since: DOM Level 3
+*/
+int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ char *encoding;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ encoding = (char *) docp->encoding;
+ ALLOC_ZVAL(*retval);
+
+ if (encoding != NULL) {
+ ZVAL_STRING(*retval, encoding, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+ xmlCharEncodingHandlerPtr handler;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+
+ handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
+
+ if (handler != NULL) {
+ xmlCharEncCloseFunc(handler);
+ if (docp->encoding != NULL) {
+ xmlFree((xmlChar *)docp->encoding);
+ }
+ docp->encoding = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Document Encoding");
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ standalone boolean
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-standalone
+Since: DOM Level 3
+*/
+int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ int standalone;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ standalone = docp->standalone;
+ ZVAL_BOOL(*retval, standalone);
+
+ return SUCCESS;
+}
+
+int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+ int standalone;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_long(newval);
+
+ standalone = Z_LVAL_P(newval);
+ if (standalone > 0) {
+ docp->standalone = 1;
+ }
+ else if (standalone < 0) {
+ docp->standalone = -1;
+ }
+ else {
+ docp->standalone = 0;
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ version string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-version
+Since: DOM Level 3
+*/
+int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ char *version;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ version = (char *) docp->version;
+ ALLOC_ZVAL(*retval);
+
+ if (version != NULL) {
+ ZVAL_STRING(*retval, version, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (docp->version != NULL) {
+ xmlFree((xmlChar *) docp->version );
+ }
+
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+
+ docp->version = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ strictErrorChecking boolean
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-strictErrorChecking
+Since: DOM Level 3
+*/
+int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->stricterror);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->stricterror = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ formatOutput boolean
+readonly=no
+*/
+int dom_document_format_output_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr 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)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->formatoutput = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ validateOnParse boolean
+readonly=no
+*/
+int dom_document_validate_on_parse_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr 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)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->validateonparse = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ resolveExternals boolean
+readonly=no
+*/
+int dom_document_resolve_externals_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr 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)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->resolveexternals = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ preserveWhiteSpace boolean
+readonly=no
+*/
+int dom_document_preserve_whitespace_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr 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)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->preservewhitespace = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ recover boolean
+readonly=no
+*/
+int dom_document_recover_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr doc_prop;
+
+ ALLOC_ZVAL(*retval);
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ ZVAL_BOOL(*retval, doc_prop->recover);
+ } else {
+ ZVAL_FALSE(*retval);
+ }
+ return SUCCESS;
+}
+
+int dom_document_recover_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->recover = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ substituteEntities boolean
+readonly=no
+*/
+int dom_document_substitue_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_doc_propsptr 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)
+{
+ zval value_copy;
+ dom_doc_propsptr doc_prop;
+
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_boolean(newval);
+
+ if (obj->document) {
+ doc_prop = dom_get_doc_props(obj->document);
+ doc_prop->substituteentities = Z_LVAL_P(newval);
+ }
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ documentURI string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-documentURI
+Since: DOM Level 3
+*/
+int dom_document_document_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp;
+ char *url;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ url = (char *) docp->URL;
+ if (url != NULL) {
+ ZVAL_STRING(*retval, url, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlDoc *docp;
+
+ docp = (xmlDocPtr) dom_object_get_node(obj);
+
+ if (docp == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (docp->URL != NULL) {
+ xmlFree((xmlChar *) docp->URL);
+ }
+
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+
+ docp->URL = xmlStrdup((const xmlChar *) Z_STRVAL_P(newval));
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ config DOMConfiguration
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-config
+Since: DOM Level 3
+*/
+int dom_document_config_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto DOMElement dom_document_create_element(string tagName [, string value]);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-2141741547
+Since:
+*/
+PHP_FUNCTION(dom_document_create_element)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ dom_object *intern;
+ int ret, name_len, value_len;
+ char *name, *value = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewDocNode(docp, NULL, name, value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_element */
+
+/* {{{ proto DOMDocumentFragment dom_document_create_document_fragment();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-35CB04B5
+Since:
+*/
+PHP_FUNCTION(dom_document_create_document_fragment)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ dom_object *intern;
+ int ret;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewDocFragment(docp);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_document_fragment */
+
+/* {{{ proto DOMText dom_document_create_text_node(string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1975348127
+Since:
+*/
+PHP_FUNCTION(dom_document_create_text_node)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len;
+ dom_object *intern;
+ char *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewDocText(docp, (xmlChar *) value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_text_node */
+
+/* {{{ proto DOMComment dom_document_create_comment(string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1334481328
+Since:
+*/
+PHP_FUNCTION(dom_document_create_comment)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len;
+ dom_object *intern;
+ char *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewDocComment(docp, (xmlChar *) value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_comment */
+
+/* {{{ proto DOMCdataSection dom_document_create_cdatasection(string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D26C0AF8
+Since:
+*/
+PHP_FUNCTION(dom_document_create_cdatasection)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len;
+ dom_object *intern;
+ char *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ node = xmlNewCDataBlock(docp, (xmlChar *) value, value_len);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_cdatasection */
+
+/* {{{ proto DOMProcessingInstruction dom_document_create_processing_instruction(string target, string data);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-135944439
+Since:
+*/
+PHP_FUNCTION(dom_document_create_processing_instruction)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp;
+ int ret, value_len, name_len = 0;
+ dom_object *intern;
+ char *name, *value = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_document_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewPI((xmlChar *) name, (xmlChar *) value);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ node->doc = docp;
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_document_create_processing_instruction */
+
+/* {{{ proto DOMAttr dom_document_create_attribute(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1084891198
+Since:
+*/
+PHP_FUNCTION(dom_document_create_attribute)
+{
+ zval *id;
+ xmlAttrPtr node;
+ xmlDocPtr docp;
+ int ret, name_len;
+ dom_object *intern;
+ char *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewDocProp(docp, (xmlChar *) name, NULL);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
+
+}
+/* }}} end dom_document_create_attribute */
+
+/* {{{ proto DOMEntityReference dom_document_create_entity_reference(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-392B75AE
+Since:
+*/
+PHP_FUNCTION(dom_document_create_entity_reference)
+{
+ zval *id;
+ xmlNode *node;
+ xmlDocPtr docp = NULL;
+ dom_object *intern;
+ int ret, name_len;
+ char *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (xmlValidateName((xmlChar *) name, 0) != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewReference(docp, name);
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) node, &ret, intern);
+}
+/* }}} end dom_document_create_entity_reference */
+
+/* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name(string tagname);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C9094
+Since:
+*/
+PHP_FUNCTION(dom_document_get_elements_by_tag_name)
+{
+ zval *id;
+ xmlDocPtr docp;
+ int name_len;
+ dom_object *intern, *namednode;
+ char *name;
+ xmlChar *local;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ local = xmlCharStrndup(name, name_len);
+ dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
+}
+/* }}} end dom_document_get_elements_by_tag_name */
+
+/* {{{ proto DOMNode dom_document_import_node(DOMNode importedNode, boolean deep);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Core-Document-importNode
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_import_node)
+{
+ zval *id, *node;
+ xmlDocPtr docp;
+ xmlNodePtr nodep, retnodep;
+ dom_object *intern, *nodeobj;
+ int ret;
+ long recursive = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &id, dom_document_class_entry, &node, dom_node_class_entry, &recursive) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ DOM_GET_OBJ(nodep, node, xmlNodePtr, nodeobj);
+
+ if (nodep->type == XML_HTML_DOCUMENT_NODE || nodep->type == XML_DOCUMENT_NODE
+ || nodep->type == XML_DOCUMENT_TYPE_NODE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot import: Node Type Not Supported");
+ RETURN_FALSE;
+ }
+
+ if (nodep->doc == docp) {
+ retnodep = nodep;
+ } else {
+ if ((recursive == 0) && (nodep->type == XML_ELEMENT_NODE)) {
+ recursive = 2;
+ }
+ retnodep = xmlDocCopyNode(nodep, docp, recursive);
+ if (!retnodep) {
+ RETURN_FALSE;
+ }
+
+ if ((retnodep->type == XML_ATTRIBUTE_NODE) && (nodep->ns != NULL)) {
+ xmlNsPtr nsptr = NULL;
+ xmlNodePtr root = xmlDocGetRootElement(docp);
+
+ nsptr = xmlSearchNsByHref (nodep->doc, root, nodep->ns->href);
+ if (nsptr == NULL) {
+ int errorcode;
+ nsptr = dom_get_ns(root, (char *) nodep->ns->href, &errorcode, (char *) nodep->ns->prefix);
+ }
+ xmlSetNs(retnodep, nsptr);
+ }
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) retnodep, &ret, intern);
+}
+/* }}} end dom_document_import_node */
+
+/* {{{ proto DOMElement dom_document_create_element_ns(string namespaceURI, string qualifiedName [,string value]);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrElNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_create_element_ns)
+{
+ zval *id;
+ xmlDocPtr docp;
+ xmlNodePtr nodep = NULL;
+ xmlNsPtr nsptr = NULL;
+ int ret, uri_len = 0, name_len = 0, value_len = 0;
+ char *uri, *name, *value = NULL;
+ char *localname = NULL, *prefix = NULL;
+ int errorcode;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s|s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+
+ if (errorcode == 0) {
+ if (xmlValidateName((xmlChar *) localname, 0) == 0) {
+ nodep = xmlNewDocNode (docp, NULL, localname, value);
+ if (nodep != NULL && uri != NULL) {
+ nsptr = xmlSearchNsByHref (nodep->doc, nodep, uri);
+ if (nsptr == NULL) {
+ nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
+ }
+ xmlSetNs(nodep, nsptr);
+ }
+ } else {
+ errorcode = INVALID_CHARACTER_ERR;
+ }
+ }
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+
+ if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeNode(nodep);
+ }
+ php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (nodep == NULL) {
+ RETURN_FALSE;
+ }
+
+
+ nodep->ns = nsptr;
+
+ DOM_RET_OBJ(nodep, &ret, intern);
+}
+/* }}} end dom_document_create_element_ns */
+
+/* {{{ proto DOMAttr dom_document_create_attribute_ns(string namespaceURI, string qualifiedName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-DocCrAttrNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_create_attribute_ns)
+{
+ zval *id;
+ xmlDocPtr docp;
+ xmlNodePtr nodep = NULL, root;
+ xmlNsPtr nsptr;
+ int ret, uri_len = 0, name_len = 0;
+ char *uri, *name;
+ char *localname = NULL, *prefix = NULL;
+ dom_object *intern;
+ int errorcode;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ root = xmlDocGetRootElement(docp);
+ if (root != NULL) {
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+ if (errorcode == 0) {
+ if (xmlValidateName((xmlChar *) localname, 0) == 0) {
+ nodep = (xmlNodePtr) xmlNewDocProp(docp, localname, NULL);
+ if (nodep != NULL && uri_len > 0) {
+ nsptr = xmlSearchNsByHref (nodep->doc, root, uri);
+ if (nsptr == NULL) {
+ nsptr = dom_get_ns(root, uri, &errorcode, prefix);
+ }
+ xmlSetNs(nodep, nsptr);
+ }
+ } else {
+ errorcode = INVALID_CHARACTER_ERR;
+ }
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Missing Root Element");
+ RETURN_FALSE;
+ }
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+
+ if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeProp((xmlAttrPtr) nodep);
+ }
+ php_dom_throw_error(errorcode, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (nodep == NULL) {
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(nodep, &ret, intern);
+}
+/* }}} end dom_document_create_attribute_ns */
+
+/* {{{ proto DOMNodeList dom_document_get_elements_by_tag_name_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBTNNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns)
+{
+ zval *id;
+ xmlDocPtr docp;
+ int uri_len, name_len;
+ dom_object *intern, *namednode;
+ char *uri, *name;
+ xmlChar *local, *nsuri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_document_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ local = xmlCharStrndup(name, name_len);
+ nsuri = xmlCharStrndup(uri, uri_len);
+ dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
+}
+/* }}} end dom_document_get_elements_by_tag_name_ns */
+
+/* {{{ proto DOMElement dom_document_get_element_by_id(string elementId);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getElBId
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_document_get_element_by_id)
+{
+ zval *id;
+ xmlDocPtr docp;
+ xmlAttrPtr attrp;
+ int ret, idname_len;
+ dom_object *intern;
+ char *idname;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &idname, &idname_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ attrp = xmlGetID(docp, (xmlChar *) idname);
+
+ if (attrp && attrp->parent) {
+ DOM_RET_OBJ((xmlNodePtr) attrp->parent, &ret, intern);
+ } else {
+ RETVAL_NULL();
+ }
+
+}
+/* }}} end dom_document_get_element_by_id */
+
+/* {{{ proto DOMNode dom_document_adopt_node(DOMNode source);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-adoptNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_adopt_node)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_document_adopt_node */
+
+/* {{{ proto void dom_document_normalize_document();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-normalizeDocument
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_normalize_document)
+{
+ zval *id;
+ xmlDocPtr docp;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ dom_normalize((xmlNodePtr) docp TSRMLS_CC);
+}
+/* }}} end dom_document_normalize_document */
+
+/* {{{ proto DOMNode dom_document_rename_node(node n, string namespaceURI, string qualifiedName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Document3-renameNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_rename_node)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_document_rename_node */
+
+/* {{{ proto void DOMDocument::__construct([string version], [string encoding]); */
+PHP_METHOD(domdocument, __construct)
+{
+
+ zval *id;
+ xmlDoc *docp = NULL, *olddoc;
+ dom_object *intern;
+ char *encoding, *version = NULL;
+ int encoding_len = 0, version_len = 0, refcount;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ss", &id, dom_document_class_entry, &version, &version_len, &encoding, &encoding_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ docp = xmlNewDoc(version);
+
+ if (!docp) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (encoding_len > 0) {
+ docp->encoding = (const xmlChar*)xmlStrdup(encoding);
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ olddoc = (xmlDocPtr) dom_object_get_node(intern);
+ if (olddoc != NULL) {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ if (refcount != 0) {
+ olddoc->_private = NULL;
+ }
+ }
+ intern->document = NULL;
+ if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC) == -1) {
+ RETURN_FALSE;
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)docp, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMDocument::__construct */
+
+char *_dom_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len TSRMLS_DC) /* {{{ */
+{
+ xmlURI *uri;
+ xmlChar *escsource;
+ char *file_dest;
+ int isFileUri = 0;
+
+ uri = xmlCreateURI();
+ escsource = xmlURIEscapeStr(source, ":");
+ xmlParseURIReference(uri, escsource);
+ xmlFree(escsource);
+
+ if (uri->scheme != NULL) {
+ /* absolute file uris - libxml only supports localhost or empty host */
+ if (strncasecmp(source, "file:///",8) == 0) {
+ isFileUri = 1;
+#ifdef PHP_WIN32
+ source += 8;
+#else
+ source += 7;
+#endif
+ } else if (strncasecmp(source, "file://localhost/",17) == 0) {
+ isFileUri = 1;
+#ifdef PHP_WIN32
+ source += 17;
+#else
+ source += 16;
+#endif
+ }
+ }
+
+ file_dest = source;
+
+ if ((uri->scheme == NULL || isFileUri)) {
+ /* XXX possible buffer overflow if VCWD_REALPATH does not know size of resolved_path */
+ if (!VCWD_REALPATH(source, resolved_path) && !expand_filepath(source, resolved_path TSRMLS_CC)) {
+ xmlFreeURI(uri);
+ return NULL;
+ }
+ file_dest = resolved_path;
+ }
+
+ xmlFreeURI(uri);
+
+ return file_dest;
+}
+/* }}} */
+
+static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, int source_len, int options TSRMLS_DC) /* {{{ */
+{
+ xmlDocPtr ret;
+ xmlParserCtxtPtr ctxt = NULL;
+ dom_doc_propsptr doc_props;
+ dom_object *intern;
+ php_libxml_ref_obj *document = NULL;
+ int validate, recover, resolve_externals, keep_blanks, substitute_ent;
+ int resolved_path_len;
+ int old_error_reporting = 0;
+ char *directory=NULL, resolved_path[MAXPATHLEN];
+
+ if (id != NULL) {
+ 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;
+ recover = doc_props->recover;
+
+ if (document == NULL) {
+ efree(doc_props);
+ }
+
+ xmlInitParser();
+
+ if (mode == DOM_LOAD_FILE) {
+ char *file_dest = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (file_dest) {
+ ctxt = xmlCreateFileParserCtxt(file_dest);
+ }
+
+ } else {
+ ctxt = xmlCreateMemoryParserCtxt(source, source_len);
+ }
+
+ if (ctxt == NULL) {
+ return(NULL);
+ }
+
+ /* If loading from memory, we need to set the base directory for the document */
+ if (mode != DOM_LOAD_FILE) {
+#if HAVE_GETCWD
+ directory = VCWD_GETCWD(resolved_path, MAXPATHLEN);
+#elif HAVE_GETWD
+ directory = VCWD_GETWD(resolved_path);
+#endif
+ if (directory) {
+ if(ctxt->directory != NULL) {
+ xmlFree((char *) ctxt->directory);
+ }
+ resolved_path_len = strlen(resolved_path);
+ if (resolved_path[resolved_path_len - 1] != DEFAULT_SLASH) {
+ resolved_path[resolved_path_len] = DEFAULT_SLASH;
+ resolved_path[++resolved_path_len] = '\0';
+ }
+ ctxt->directory = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
+ }
+ }
+
+ ctxt->vctxt.error = php_libxml_ctx_error;
+ ctxt->vctxt.warning = php_libxml_ctx_warning;
+
+ if (ctxt->sax != NULL) {
+ ctxt->sax->error = php_libxml_ctx_error;
+ ctxt->sax->warning = php_libxml_ctx_warning;
+ }
+
+ if (validate && ! (options & XML_PARSE_DTDVALID)) {
+ options |= XML_PARSE_DTDVALID;
+ }
+ if (resolve_externals && ! (options & XML_PARSE_DTDATTR)) {
+ options |= XML_PARSE_DTDATTR;
+ }
+ if (substitute_ent && ! (options & XML_PARSE_NOENT)) {
+ options |= XML_PARSE_NOENT;
+ }
+ if (keep_blanks == 0 && ! (options & XML_PARSE_NOBLANKS)) {
+ options |= XML_PARSE_NOBLANKS;
+ }
+
+ xmlCtxtUseOptions(ctxt, options);
+
+ ctxt->recovery = recover;
+ if (recover) {
+ old_error_reporting = EG(error_reporting);
+ EG(error_reporting) = old_error_reporting | E_WARNING;
+ }
+
+ xmlParseDocument(ctxt);
+
+ if (ctxt->wellFormed || recover) {
+ ret = ctxt->myDoc;
+ if (ctxt->recovery) {
+ EG(error_reporting) = old_error_reporting;
+ }
+ /* If loading from memory, set the base reference uri for the document */
+ if (ret && ret->URL == NULL && ctxt->directory != NULL) {
+ ret->URL = xmlStrdup(ctxt->directory);
+ }
+ } else {
+ ret = NULL;
+ xmlFreeDoc(ctxt->myDoc);
+ ctxt->myDoc = NULL;
+ }
+
+ xmlFreeParserCtxt(ctxt);
+
+ return(ret);
+}
+/* }}} */
+
+/* {{{ static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) */
+static void dom_parse_document(INTERNAL_FUNCTION_PARAMETERS, int mode) {
+ zval *id;
+ xmlDoc *docp = NULL, *newdoc;
+ dom_doc_propsptr doc_prop;
+ dom_object *intern;
+ char *source;
+ int source_len, refcount, ret;
+ long options = 0;
+
+ id = getThis();
+ if (id != NULL && ! instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
+ id = NULL;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
+ return;
+ }
+
+ if (!source_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
+ RETURN_FALSE;
+ }
+
+ newdoc = dom_document_parser(id, mode, source, source_len, options TSRMLS_CC);
+
+ if (!newdoc)
+ RETURN_FALSE;
+
+ if (id != NULL) {
+ 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) {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ doc_prop = intern->document->doc_props;
+ intern->document->doc_props = NULL;
+ refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ if (refcount != 0) {
+ docp->_private = NULL;
+ }
+ }
+ intern->document = NULL;
+ if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
+ RETURN_FALSE;
+ }
+ intern->document->doc_props = doc_prop;
+ }
+
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
+
+ RETURN_TRUE;
+ } else {
+ DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
+ }
+}
+/* }}} end dom_parser_document */
+
+/* {{{ proto DOMNode dom_document_load(string source [, int options]);
+URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-load
+Since: DOM Level 3
+*/
+PHP_METHOD(domdocument, load)
+{
+ dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_load */
+
+/* {{{ proto DOMNode dom_document_loadxml(string source [, int options]);
+URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-loadXML
+Since: DOM Level 3
+*/
+PHP_METHOD(domdocument, loadXML)
+{
+ dom_parse_document(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_loadxml */
+
+/* {{{ proto int dom_document_save(string file);
+Convenience method to save to file
+*/
+PHP_FUNCTION(dom_document_save)
+{
+ zval *id;
+ xmlDoc *docp;
+ int file_len = 0, bytes, format, saveempty = 0;
+ dom_object *intern;
+ dom_doc_propsptr doc_props;
+ char *file;
+ long options = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &id, dom_document_class_entry, &file, &file_len, &options) == FAILURE) {
+ return;
+ }
+
+ if (file_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ /* encoding handled by property on doc */
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ saveempty = xmlSaveNoEmptyTags;
+ xmlSaveNoEmptyTags = 1;
+ }
+ bytes = xmlSaveFormatFileEnc(file, docp, NULL, format);
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+ if (bytes == -1) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(bytes);
+}
+/* }}} end dom_document_save */
+
+/* {{{ proto string dom_document_savexml([node n]);
+URL: http://www.w3.org/TR/DOM-Level-3-LS/load-save.html#LS-DocumentLS-saveXML
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_document_savexml)
+{
+ zval *id, *nodep = NULL;
+ xmlDoc *docp;
+ xmlNode *node;
+ xmlBufferPtr buf;
+ xmlChar *mem;
+ dom_object *intern, *nodeobj;
+ dom_doc_propsptr doc_props;
+ int size, format, saveempty = 0;
+ long options = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, &options) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+
+ if (nodep != NULL) {
+ /* Dump contents of Node */
+ DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
+ if (node->doc != docp) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ buf = xmlBufferCreate();
+ if (!buf) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
+ RETURN_FALSE;
+ }
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ saveempty = xmlSaveNoEmptyTags;
+ xmlSaveNoEmptyTags = 1;
+ }
+ xmlNodeDump(buf, docp, node, 0, format);
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+ mem = (xmlChar*) xmlBufferContent(buf);
+ if (!mem) {
+ xmlBufferFree(buf);
+ RETURN_FALSE;
+ }
+ RETVAL_STRING(mem, 1);
+ xmlBufferFree(buf);
+ } else {
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ saveempty = xmlSaveNoEmptyTags;
+ xmlSaveNoEmptyTags = 1;
+ }
+ /* Encoding is handled from the encoding property set on the document */
+ xmlDocDumpFormatMemory(docp, &mem, &size, format);
+ if (options & LIBXML_SAVE_NOEMPTYTAG) {
+ xmlSaveNoEmptyTags = saveempty;
+ }
+ if (!size) {
+ RETURN_FALSE;
+ }
+ RETVAL_STRINGL(mem, size, 1);
+ xmlFree(mem);
+ }
+}
+/* }}} end dom_document_savexml */
+
+static xmlNodePtr php_dom_free_xinclude_node(xmlNodePtr cur TSRMLS_DC) /* {{{ */
+{
+ xmlNodePtr xincnode;
+
+ xincnode = cur;
+ cur = cur->next;
+ xmlUnlinkNode(xincnode);
+ php_libxml_node_free_resource(xincnode TSRMLS_CC);
+
+ return cur;
+}
+/* }}} */
+
+static void php_dom_remove_xinclude_nodes(xmlNodePtr cur TSRMLS_DC) /* {{{ */
+{
+ while(cur) {
+ if (cur->type == XML_XINCLUDE_START) {
+ cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
+
+ /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */
+ while(cur && cur->type != XML_XINCLUDE_END) {
+ /* remove xinclude processing nodes from recursive xincludes */
+ if (cur->type == XML_ELEMENT_NODE) {
+ php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
+ }
+ cur = cur->next;
+ }
+
+ if (cur && cur->type == XML_XINCLUDE_END) {
+ cur = php_dom_free_xinclude_node(cur TSRMLS_CC);
+ }
+ } else {
+ if (cur->type == XML_ELEMENT_NODE) {
+ php_dom_remove_xinclude_nodes(cur->children TSRMLS_CC);
+ }
+ cur = cur->next;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto int dom_document_xinclude([int options])
+ Substitutues xincludes in a DomDocument */
+PHP_FUNCTION(dom_document_xinclude)
+{
+ zval *id;
+ xmlDoc *docp;
+ xmlNodePtr root;
+ long flags = 0;
+ int err;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_document_class_entry, &flags) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ err = xmlXIncludeProcessFlags(docp, flags);
+
+ /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
+ are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
+ but are not wanted in resulting document - must be done even if err as it could fail after
+ having processed some xincludes */
+ root = (xmlNodePtr) docp->children;
+ while(root && root->type != XML_ELEMENT_NODE && root->type != XML_XINCLUDE_START) {
+ root = root->next;
+ }
+ if (root) {
+ php_dom_remove_xinclude_nodes(root TSRMLS_CC);
+ }
+
+ if (err) {
+ RETVAL_LONG(err);
+ } else {
+ RETVAL_FALSE;
+ }
+
+}
+/* }}} */
+
+/* {{{ proto boolean dom_document_validate();
+Since: DOM extended
+*/
+PHP_FUNCTION(dom_document_validate)
+{
+ zval *id;
+ xmlDoc *docp;
+ dom_object *intern;
+ xmlValidCtxt *cvp;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_document_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ cvp = xmlNewValidCtxt();
+
+ cvp->userData = NULL;
+ cvp->error = (xmlValidityErrorFunc) php_libxml_error_handler;
+ cvp->warning = (xmlValidityErrorFunc) php_libxml_error_handler;
+
+ if (xmlValidateDocument(cvp, docp)) {
+ RETVAL_TRUE;
+ } else {
+ RETVAL_FALSE;
+ }
+
+ xmlFreeValidCtxt(cvp);
+
+}
+/* }}} */
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ zval *id;
+ xmlDoc *docp;
+ dom_object *intern;
+ char *source = NULL, *valid_file = NULL;
+ int source_len = 0;
+ xmlSchemaParserCtxtPtr parser;
+ xmlSchemaPtr sptr;
+ xmlSchemaValidCtxtPtr vptr;
+ int is_valid;
+ char resolved_path[MAXPATHLEN + 1];
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
+ return;
+ }
+
+ if (source_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ switch (type) {
+ case DOM_LOAD_FILE:
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (!valid_file) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema file source");
+ RETURN_FALSE;
+ }
+ parser = xmlSchemaNewParserCtxt(valid_file);
+ break;
+ case DOM_LOAD_STRING:
+ parser = xmlSchemaNewMemParserCtxt(source, source_len);
+ /* If loading from memory, we need to set the base directory for the document
+ but it is not apparent how to do that for schema's */
+ break;
+ default:
+ return;
+ }
+
+ xmlSchemaSetParserErrors(parser,
+ (xmlSchemaValidityErrorFunc) php_libxml_error_handler,
+ (xmlSchemaValidityWarningFunc) php_libxml_error_handler,
+ parser);
+ sptr = xmlSchemaParse(parser);
+ xmlSchemaFreeParserCtxt(parser);
+ if (!sptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema");
+ RETURN_FALSE;
+ }
+
+ docp = (xmlDocPtr) dom_object_get_node(intern);
+
+ vptr = xmlSchemaNewValidCtxt(sptr);
+ if (!vptr) {
+ xmlSchemaFree(sptr);
+ php_error(E_ERROR, "Invalid Schema Validation Context");
+ RETURN_FALSE;
+ }
+
+ xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+ is_valid = xmlSchemaValidateDoc(vptr, docp);
+ xmlSchemaFree(sptr);
+ xmlSchemaFreeValidCtxt(vptr);
+
+ if (is_valid == 0) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto boolean dom_document_schema_validate_file(string filename); */
+PHP_FUNCTION(dom_document_schema_validate_file)
+{
+ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_schema_validate_file */
+
+/* {{{ proto boolean dom_document_schema_validate(string source); */
+PHP_FUNCTION(dom_document_schema_validate_xml)
+{
+ _dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_schema_validate */
+
+static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ zval *id;
+ xmlDoc *docp;
+ dom_object *intern;
+ char *source = NULL, *valid_file = NULL;
+ int source_len = 0;
+ xmlRelaxNGParserCtxtPtr parser;
+ xmlRelaxNGPtr sptr;
+ xmlRelaxNGValidCtxtPtr vptr;
+ int is_valid;
+ char resolved_path[MAXPATHLEN + 1];
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
+ return;
+ }
+
+ if (source_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Schema source");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ switch (type) {
+ case DOM_LOAD_FILE:
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN TSRMLS_CC);
+ if (!valid_file) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG file source");
+ RETURN_FALSE;
+ }
+ parser = xmlRelaxNGNewParserCtxt(valid_file);
+ break;
+ case DOM_LOAD_STRING:
+ parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
+ /* If loading from memory, we need to set the base directory for the document
+ but it is not apparent how to do that for schema's */
+ break;
+ default:
+ return;
+ }
+
+ xmlRelaxNGSetParserErrors(parser,
+ (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
+ (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
+ parser);
+ sptr = xmlRelaxNGParse(parser);
+ xmlRelaxNGFreeParserCtxt(parser);
+ if (!sptr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid RelaxNG");
+ RETURN_FALSE;
+ }
+
+ docp = (xmlDocPtr) dom_object_get_node(intern);
+
+ vptr = xmlRelaxNGNewValidCtxt(sptr);
+ if (!vptr) {
+ xmlRelaxNGFree(sptr);
+ php_error(E_ERROR, "Invalid RelaxNG Validation Context");
+ RETURN_FALSE;
+ }
+
+ xmlRelaxNGSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+ is_valid = xmlRelaxNGValidateDoc(vptr, docp);
+ xmlRelaxNGFree(sptr);
+ xmlRelaxNGFreeValidCtxt(vptr);
+
+ if (is_valid == 0) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto boolean dom_document_relaxNG_validate_file(string filename); */
+PHP_FUNCTION(dom_document_relaxNG_validate_file)
+{
+ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_relaxNG_validate_file */
+
+/* {{{ proto boolean dom_document_relaxNG_validate_xml(string source); */
+PHP_FUNCTION(dom_document_relaxNG_validate_xml)
+{
+ _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_relaxNG_validate_xml */
+
+#endif
+
+#if defined(LIBXML_HTML_ENABLED)
+
+static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
+{
+ zval *id;
+ xmlDoc *docp = NULL, *newdoc;
+ dom_object *intern;
+ dom_doc_propsptr doc_prop;
+ char *source;
+ int source_len, refcount, ret;
+ long options = 0;
+ htmlParserCtxtPtr ctxt;
+
+ id = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &source, &source_len, &options) == FAILURE) {
+ return;
+ }
+
+ if (!source_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty string supplied as input");
+ RETURN_FALSE;
+ }
+
+ if (mode == DOM_LOAD_FILE) {
+ ctxt = htmlCreateFileParserCtxt(source, NULL);
+ } else {
+ source_len = xmlStrlen(source);
+ ctxt = htmlCreateMemoryParserCtxt(source, source_len);
+ }
+
+ if (!ctxt) {
+ RETURN_FALSE;
+ }
+
+ if (options) {
+ htmlCtxtUseOptions(ctxt, options);
+ }
+
+ ctxt->vctxt.error = php_libxml_ctx_error;
+ ctxt->vctxt.warning = php_libxml_ctx_warning;
+ if (ctxt->sax != NULL) {
+ ctxt->sax->error = php_libxml_ctx_error;
+ ctxt->sax->warning = php_libxml_ctx_warning;
+ }
+ htmlParseDocument(ctxt);
+ newdoc = ctxt->myDoc;
+ htmlFreeParserCtxt(ctxt);
+
+ if (!newdoc)
+ RETURN_FALSE;
+
+ if (id != NULL && instanceof_function(Z_OBJCE_P(id), dom_document_class_entry TSRMLS_CC)) {
+ 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) {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ doc_prop = intern->document->doc_props;
+ intern->document->doc_props = NULL;
+ refcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ if (refcount != 0) {
+ docp->_private = NULL;
+ }
+ }
+ intern->document = NULL;
+ if (php_libxml_increment_doc_ref((php_libxml_node_object *)intern, newdoc TSRMLS_CC) == -1) {
+ RETURN_FALSE;
+ }
+ intern->document->doc_props = doc_prop;
+ }
+
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, (xmlNodePtr)newdoc, (void *)intern TSRMLS_CC);
+
+ RETURN_TRUE;
+ } else {
+ DOM_RET_OBJ((xmlNodePtr) newdoc, &ret, NULL);
+ }
+}
+/* }}} */
+
+/* {{{ proto DOMNode dom_document_load_html_file(string source);
+Since: DOM extended
+*/
+PHP_METHOD(domdocument, loadHTMLFile)
+{
+ dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
+}
+/* }}} end dom_document_load_html_file */
+
+/* {{{ proto DOMNode dom_document_load_html(string source);
+Since: DOM extended
+*/
+PHP_METHOD(domdocument, loadHTML)
+{
+ dom_load_html(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
+}
+/* }}} end dom_document_load_html */
+
+/* {{{ proto int dom_document_save_html_file(string file);
+Convenience method to save to file as html
+*/
+PHP_FUNCTION(dom_document_save_html_file)
+{
+ zval *id;
+ xmlDoc *docp;
+ int file_len, bytes, format;
+ dom_object *intern;
+ dom_doc_propsptr doc_props;
+ char *file;
+ const char *encoding;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_document_class_entry, &file, &file_len) == FAILURE) {
+ return;
+ }
+
+ if (file_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Filename");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+
+ encoding = (const char *) htmlGetMetaEncoding(docp);
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+ bytes = htmlSaveFileFormat(file, docp, encoding, format);
+
+ if (bytes == -1) {
+ RETURN_FALSE;
+ }
+ RETURN_LONG(bytes);
+}
+/* }}} end dom_document_save_html_file */
+
+/* {{{ proto string dom_document_save_html();
+Convenience method to output as html
+*/
+PHP_FUNCTION(dom_document_save_html)
+{
+ zval *id, *nodep = NULL;
+ xmlDoc *docp;
+ xmlNode *node;
+ xmlBufferPtr buf;
+ dom_object *intern, *nodeobj;
+ xmlChar *mem = NULL;
+ int size, format;
+ dom_doc_propsptr doc_props;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O|O!", &id, dom_document_class_entry, &nodep, dom_node_class_entry)
+ == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ doc_props = dom_get_doc_props(intern->document);
+ format = doc_props->formatoutput;
+
+ if (nodep != NULL) {
+ /* Dump contents of Node */
+ DOM_GET_OBJ(node, nodep, xmlNodePtr, nodeobj);
+ if (node->doc != docp) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ buf = xmlBufferCreate();
+ if (!buf) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch buffer");
+ RETURN_FALSE;
+ }
+
+ size = htmlNodeDump(buf, docp, node);
+ if (size >= 0) {
+ mem = (xmlChar*) xmlBufferContent(buf);
+ if (!mem) {
+ RETVAL_FALSE;
+ } else {
+ RETVAL_STRINGL((const char*) mem, size, 1);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error dumping HTML node");
+ RETVAL_FALSE;
+ }
+ xmlBufferFree(buf);
+ } else {
+#if LIBXML_VERSION >= 20623
+ htmlDocDumpMemoryFormat(docp, &mem, &size, format);
+#else
+ htmlDocDumpMemory(docp, &mem, &size);
+#endif
+ if (!size) {
+ RETVAL_FALSE;
+ } else {
+ RETVAL_STRINGL((const char*) mem, size, 1);
+ }
+ if (mem)
+ xmlFree(mem);
+ }
+
+}
+/* }}} end dom_document_save_html */
+
+#endif /* defined(LIBXML_HTML_ENABLED) */
+
+/* {{{ proto boolean DOMDocument::registerNodeClass(string baseclass, string extendedclass);
+ Register extended class used to create base node type */
+PHP_METHOD(domdocument, registerNodeClass)
+{
+ zval *id;
+ xmlDoc *docp;
+ char *baseclass = NULL, *extendedclass = NULL;
+ int baseclass_len = 0, extendedclass_len = 0;
+ zend_class_entry *basece = NULL, *ce = NULL;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss!", &id, dom_document_class_entry, &baseclass, &baseclass_len, &extendedclass, &extendedclass_len) == FAILURE) {
+ return;
+ }
+
+ if (baseclass_len) {
+ zend_class_entry **pce;
+ if (zend_lookup_class(baseclass, baseclass_len, &pce TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", baseclass);
+ return;
+ }
+ basece = *pce;
+ }
+
+ if (basece == NULL || ! instanceof_function(basece, dom_node_class_entry TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from DOMNode.", baseclass);
+ return;
+ }
+
+ if (extendedclass_len) {
+ zend_class_entry **pce;
+ if (zend_lookup_class(extendedclass, extendedclass_len, &pce TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s does not exist", extendedclass);
+ }
+ ce = *pce;
+ }
+
+ if (ce == NULL || instanceof_function(ce, basece TSRMLS_CC)) {
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
+ if (dom_set_doc_classmap(intern->document, basece, ce TSRMLS_CC) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s could not be registered.", extendedclass);
+ }
+ RETURN_TRUE;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Class %s is not derived from %s.", extendedclass, baseclass);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+#endif /* HAVE_LIBXML && HAVE_DOM */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c
new file mode 100644
index 0000000..4e8d660
--- /dev/null
+++ b/ext/dom/documentfragment.c
@@ -0,0 +1,168 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_construct, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_documentfragement_appendXML, 0, 0, 1)
+ ZEND_ARG_INFO(0, data)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMDocumentFragment extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-B63ED1A3
+* Since:
+*/
+
+const zend_function_entry php_dom_documentfragment_class_functions[] = {
+ PHP_ME(domdocumentfragment, __construct, arginfo_dom_documentfragement_construct, ZEND_ACC_PUBLIC)
+ PHP_ME(domdocumentfragment, appendXML, arginfo_dom_documentfragement_appendXML, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* {{{ proto void DOMDocumentFragment::__construct(); */
+PHP_METHOD(domdocumentfragment, __construct)
+{
+
+ zval *id;
+ xmlNodePtr nodep = NULL, oldnode = NULL;
+ dom_object *intern;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_documentfragment_class_entry) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ nodep = xmlNewDocFragment(NULL);
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ /* php_dom_set_object(intern, nodep TSRMLS_CC); */
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMDocumentFragment::__construct */
+
+/* php_dom_xmlSetTreeDoc is a custom implementation of xmlSetTreeDoc
+ needed for hack in appendXML due to libxml bug - no need to share this function */
+static void php_dom_xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) /* {{{ */
+{
+ xmlAttrPtr prop;
+ xmlNodePtr cur;
+
+ if (tree) {
+ if(tree->type == XML_ELEMENT_NODE) {
+ prop = tree->properties;
+ while (prop != NULL) {
+ prop->doc = doc;
+ if (prop->children) {
+ cur = prop->children;
+ while (cur != NULL) {
+ php_dom_xmlSetTreeDoc(cur, doc);
+ cur = cur->next;
+ }
+ }
+ prop = prop->next;
+ }
+ }
+ if (tree->children != NULL) {
+ cur = tree->children;
+ while (cur != NULL) {
+ php_dom_xmlSetTreeDoc(cur, doc);
+ cur = cur->next;
+ }
+ }
+ tree->doc = doc;
+ }
+}
+/* }}} */
+
+/* {{{ proto void DOMDocumentFragment::appendXML(string data); */
+PHP_METHOD(domdocumentfragment, appendXML) {
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+ char *data = NULL;
+ int data_len = 0;
+ int err;
+ xmlNodePtr lst;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_documentfragment_class_entry, &data, &data_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (data) {
+ err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, data, &lst);
+ if (err != 0) {
+ RETURN_FALSE;
+ }
+ /* Following needed due to bug in libxml2 <= 2.6.14
+ ifdef after next libxml release as bug is fixed in their cvs */
+ php_dom_xmlSetTreeDoc(lst, nodep->doc);
+ /* End stupid hack */
+
+ xmlAddChildList(nodep,lst);
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c
new file mode 100644
index 0000000..570999a
--- /dev/null
+++ b/ext/dom/documenttype.c
@@ -0,0 +1,235 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/*
+* class DOMDocumentType extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-412266927
+* Since:
+*/
+
+const zend_function_entry php_dom_documenttype_class_functions[] = {
+ PHP_FE_END
+};
+
+/* {{{ name string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1844763134
+Since:
+*/
+int dom_documenttype_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDtdPtr dtdptr;
+
+ dtdptr = (xmlDtdPtr) dom_object_get_node(obj);
+
+ if (dtdptr == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, (char *) (dtdptr->name), 1);
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ entities DOMNamedNodeMap
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1788794630
+Since:
+*/
+int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDtdPtr doctypep;
+ xmlHashTable *entityht;
+ dom_object *intern;
+
+ doctypep = (xmlDtdPtr) dom_object_get_node(obj);
+
+ if (doctypep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ MAKE_STD_ZVAL(*retval);
+ php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
+
+ entityht = (xmlHashTable *) doctypep->entities;
+
+ intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+ dom_namednode_iter(obj, XML_ENTITY_NODE, intern, entityht, NULL, NULL TSRMLS_CC);
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ notations DOMNamedNodeMap
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D46829EF
+Since:
+*/
+int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDtdPtr doctypep;
+ xmlHashTable *notationht;
+ dom_object *intern;
+
+ doctypep = (xmlDtdPtr) dom_object_get_node(obj);
+
+ if (doctypep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ MAKE_STD_ZVAL(*retval);
+ php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
+
+ notationht = (xmlHashTable *) doctypep->notations;
+
+ intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+ dom_namednode_iter(obj, XML_NOTATION_NODE, intern, notationht, NULL, NULL TSRMLS_CC);
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ publicId string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-Core-DocType-publicId
+Since: DOM Level 2
+*/
+int dom_documenttype_public_id_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDtdPtr dtdptr;
+
+ dtdptr = (xmlDtdPtr) dom_object_get_node(obj);
+
+ if (dtdptr == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (dtdptr->ExternalID) {
+ ZVAL_STRING(*retval, (char *) (dtdptr->ExternalID), 1);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+ return SUCCESS;
+
+}
+
+/* }}} */
+
+/* {{{ systemId string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-Core-DocType-systemId
+Since: DOM Level 2
+*/
+int dom_documenttype_system_id_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDtdPtr dtdptr;
+
+ dtdptr = (xmlDtdPtr) dom_object_get_node(obj);
+
+ if (dtdptr == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (dtdptr->SystemID) {
+ ZVAL_STRING(*retval, (char *) (dtdptr->SystemID), 1);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ internalSubset string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-Core-DocType-internalSubset
+Since: DOM Level 2
+*/
+int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+
+ xmlDtdPtr dtdptr;
+ xmlDtd *intsubset;
+ xmlOutputBuffer *buff = NULL;
+
+ dtdptr = (xmlDtdPtr) dom_object_get_node(obj);
+
+ if (dtdptr == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (dtdptr->doc != NULL && ((intsubset = dtdptr->doc->intSubset) != NULL)) {
+ buff = xmlAllocOutputBuffer(NULL);
+ if (buff != NULL) {
+ xmlNodeDumpOutput (buff, NULL, (xmlNodePtr) intsubset, 0, 0, NULL);
+ xmlOutputBufferFlush(buff);
+#ifdef LIBXML2_NEW_BUFFER
+ ZVAL_STRINGL(*retval, xmlOutputBufferGetContent(buff), xmlOutputBufferGetSize(buff), 1);
+#else
+ ZVAL_STRINGL(*retval, buff->buffer->content, buff->buffer->use, 1);
+#endif
+ (void)xmlOutputBufferClose(buff);
+ return SUCCESS;
+ }
+ }
+
+ ZVAL_EMPTY_STRING(*retval);
+
+ return SUCCESS;
+
+}
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/dom.dsp b/ext/dom/dom.dsp
new file mode 100644
index 0000000..f2ae5b1
--- /dev/null
+++ b/ext/dom/dom.dsp
@@ -0,0 +1,250 @@
+# Microsoft Developer Studio Project File - Name="dom" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=dom - Win32 Release_TS
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "dom.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "dom.mak" CFG="dom - Win32 Release_TS"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "dom - Win32 Release_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "dom - Win32 Debug_TS" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "dom - Win32 Release_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release_TS"
+# PROP BASE Intermediate_Dir "Release_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_TS"
+# PROP Intermediate_Dir "Release_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\..\Zend" /I "..\..\..\TSRM" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_DOM" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=0 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DOM_EXPORTS" /D "COMPILE_DL_DOM" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DOM=1 /D "LIBXML_THREAD_ENABLED" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 wsock32.lib php5ts.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /machine:I386 /out:"..\..\Release_TS/php_dom.dll" /implib:"..\..\Release_TS/php_dom.lib" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\bindlib_w32\Release"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "dom - Win32 Debug_TS"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug_TS"
+# PROP BASE Intermediate_Dir "Debug_TS"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug_TS"
+# PROP Intermediate_Dir "Debug_TS"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "mssql-70" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "COMPILE_DL_DOM" /D ZTS=1 /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\.." /I "..\..\Zend" /I "..\..\TSRM" /I "..\..\main" /D ZEND_DEBUG=1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DOM_EXPORTS" /D "COMPILE_DL_DOM" /D ZTS=1 /D "ZEND_WIN32" /D "PHP_WIN32" /D HAVE_DOM=1 /D LIBXML_THREAD_ENABLED=1 /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x406 /d "NDEBUG"
+# ADD RSC /l 0x406 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php5ts.lib /nologo /dll /machine:I386
+# ADD LINK32 php5ts_debug.lib ws2_32.lib resolv.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /debug /machine:I386 /nodefaultlib:"msvcrt" /out:"..\..\Debug_TS\php_dom.dll" /implib:"..\..\Debug_TS/php_dom.lib" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\bindlib_w32\Release"
+
+!ENDIF
+
+# Begin Target
+
+# Name "dom - Win32 Release_TS"
+# Name "dom - Win32 Debug_TS"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\attr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\cdatasection.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\characterdata.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\comment.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\document.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\documentfragment.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\documenttype.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domconfiguration.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domerror.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domerrorhandler.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domexception.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domimplementation.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domimplementationlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domimplementationsource.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domlocator.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\domstringlist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\element.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\entity.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\entityreference.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\namednodemap.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\namelist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\node.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\nodelist.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\notation.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dom.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\processinginstruction.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\string_extend.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\text.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\typeinfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\userdatahandler.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\xpath.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\dom_ce.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dom_fe.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\dom_properties.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\php_dom.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\xml_common.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/ext/dom/dom_ce.h b/ext/dom/dom_ce.h
new file mode 100644
index 0000000..8caf002
--- /dev/null
+++ b/ext/dom/dom_ce.h
@@ -0,0 +1,66 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+#ifndef DOM_CE_H
+#define DOM_CE_H
+
+extern zend_class_entry *dom_domexception_class_entry;
+extern zend_class_entry *dom_domstringlist_class_entry;
+extern zend_class_entry *dom_namelist_class_entry;
+extern zend_class_entry *dom_domimplementationlist_class_entry;
+extern zend_class_entry *dom_domimplementationsource_class_entry;
+extern zend_class_entry *dom_domimplementation_class_entry;
+extern zend_class_entry *dom_documentfragment_class_entry;
+extern zend_class_entry *dom_document_class_entry;
+extern zend_class_entry *dom_nodelist_class_entry;
+extern zend_class_entry *dom_namednodemap_class_entry;
+extern zend_class_entry *dom_characterdata_class_entry;
+extern zend_class_entry *dom_attr_class_entry;
+extern zend_class_entry *dom_element_class_entry;
+extern zend_class_entry *dom_text_class_entry;
+extern zend_class_entry *dom_comment_class_entry;
+extern zend_class_entry *dom_typeinfo_class_entry;
+extern zend_class_entry *dom_userdatahandler_class_entry;
+extern zend_class_entry *dom_domerror_class_entry;
+extern zend_class_entry *dom_domerrorhandler_class_entry;
+extern zend_class_entry *dom_domlocator_class_entry;
+extern zend_class_entry *dom_domconfiguration_class_entry;
+extern zend_class_entry *dom_cdatasection_class_entry;
+extern zend_class_entry *dom_documenttype_class_entry;
+extern zend_class_entry *dom_notation_class_entry;
+extern zend_class_entry *dom_entity_class_entry;
+extern zend_class_entry *dom_entityreference_class_entry;
+extern zend_class_entry *dom_processinginstruction_class_entry;
+extern zend_class_entry *dom_string_extend_class_entry;
+#if defined(LIBXML_XPATH_ENABLED)
+extern zend_class_entry *dom_xpath_class_entry;
+#endif
+extern zend_class_entry *dom_namespace_node_class_entry;
+
+#endif /* DOM_CE_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h
new file mode 100644
index 0000000..3778c95
--- /dev/null
+++ b/ext/dom/dom_fe.h
@@ -0,0 +1,280 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+#ifndef DOM_FE_H
+#define DOM_FE_H
+
+extern const zend_function_entry php_dom_domexception_class_functions[];
+extern const zend_function_entry php_dom_domstringlist_class_functions[];
+extern const zend_function_entry php_dom_namelist_class_functions[];
+extern const zend_function_entry php_dom_domimplementationlist_class_functions[];
+extern const zend_function_entry php_dom_domimplementationsource_class_functions[];
+extern const zend_function_entry php_dom_domimplementation_class_functions[];
+extern const zend_function_entry php_dom_documentfragment_class_functions[];
+extern const zend_function_entry php_dom_document_class_functions[];
+extern const zend_function_entry php_dom_node_class_functions[];
+extern const zend_function_entry php_dom_nodelist_class_functions[];
+extern const zend_function_entry php_dom_namednodemap_class_functions[];
+extern const zend_function_entry php_dom_characterdata_class_functions[];
+extern const zend_function_entry php_dom_attr_class_functions[];
+extern const zend_function_entry php_dom_element_class_functions[];
+extern const zend_function_entry php_dom_text_class_functions[];
+extern const zend_function_entry php_dom_comment_class_functions[];
+extern const zend_function_entry php_dom_typeinfo_class_functions[];
+extern const zend_function_entry php_dom_userdatahandler_class_functions[];
+extern const zend_function_entry php_dom_domerror_class_functions[];
+extern const zend_function_entry php_dom_domerrorhandler_class_functions[];
+extern const zend_function_entry php_dom_domlocator_class_functions[];
+extern const zend_function_entry php_dom_domconfiguration_class_functions[];
+extern const zend_function_entry php_dom_cdatasection_class_functions[];
+extern const zend_function_entry php_dom_documenttype_class_functions[];
+extern const zend_function_entry php_dom_notation_class_functions[];
+extern const zend_function_entry php_dom_entity_class_functions[];
+extern const zend_function_entry php_dom_entityreference_class_functions[];
+extern const zend_function_entry php_dom_processinginstruction_class_functions[];
+extern const zend_function_entry php_dom_string_extend_class_functions[];
+extern const zend_function_entry php_dom_xpath_class_functions[];
+
+/* domexception errors */
+typedef enum {
+/* PHP_ERR is non-spec code for PHP errors: */
+ PHP_ERR = 0,
+ INDEX_SIZE_ERR = 1,
+ DOMSTRING_SIZE_ERR = 2,
+ HIERARCHY_REQUEST_ERR = 3,
+ WRONG_DOCUMENT_ERR = 4,
+ INVALID_CHARACTER_ERR = 5,
+ NO_DATA_ALLOWED_ERR = 6,
+ NO_MODIFICATION_ALLOWED_ERR = 7,
+ NOT_FOUND_ERR = 8,
+ NOT_SUPPORTED_ERR = 9,
+ INUSE_ATTRIBUTE_ERR = 10,
+/* Introduced in DOM Level 2: */
+ INVALID_STATE_ERR = 11,
+/* Introduced in DOM Level 2: */
+ SYNTAX_ERR = 12,
+/* Introduced in DOM Level 2: */
+ INVALID_MODIFICATION_ERR = 13,
+/* Introduced in DOM Level 2: */
+ NAMESPACE_ERR = 14,
+/* Introduced in DOM Level 2: */
+ INVALID_ACCESS_ERR = 15,
+/* Introduced in DOM Level 3: */
+ VALIDATION_ERR = 16
+} dom_exception_code;
+
+/* domstringlist methods */
+PHP_FUNCTION(dom_domstringlist_item);
+
+/* domnamelist methods */
+PHP_FUNCTION(dom_namelist_get_name);
+PHP_FUNCTION(dom_namelist_get_namespace_uri);
+
+/* domimplementationlist methods */
+PHP_FUNCTION(dom_domimplementationlist_item);
+
+/* domimplementationsource methods */
+PHP_FUNCTION(dom_domimplementationsource_get_domimplementation);
+PHP_FUNCTION(dom_domimplementationsource_get_domimplementations);
+
+/* domimplementation methods */
+PHP_METHOD(domimplementation, hasFeature);
+PHP_METHOD(domimplementation, createDocumentType);
+PHP_METHOD(domimplementation, createDocument);
+PHP_METHOD(domimplementation, getFeature);
+
+/* domdocumentfragment methods */
+PHP_METHOD(domdocumentfragment, __construct);
+PHP_METHOD(domdocumentfragment, appendXML);
+
+/* domdocument methods */
+PHP_FUNCTION(dom_document_create_element);
+PHP_FUNCTION(dom_document_create_document_fragment);
+PHP_FUNCTION(dom_document_create_text_node);
+PHP_FUNCTION(dom_document_create_comment);
+PHP_FUNCTION(dom_document_create_cdatasection);
+PHP_FUNCTION(dom_document_create_processing_instruction);
+PHP_FUNCTION(dom_document_create_attribute);
+PHP_FUNCTION(dom_document_create_entity_reference);
+PHP_FUNCTION(dom_document_get_elements_by_tag_name);
+PHP_FUNCTION(dom_document_import_node);
+PHP_FUNCTION(dom_document_create_element_ns);
+PHP_FUNCTION(dom_document_create_attribute_ns);
+PHP_FUNCTION(dom_document_get_elements_by_tag_name_ns);
+PHP_FUNCTION(dom_document_get_element_by_id);
+PHP_FUNCTION(dom_document_adopt_node);
+PHP_FUNCTION(dom_document_normalize_document);
+PHP_FUNCTION(dom_document_rename_node);
+PHP_METHOD(domdocument, __construct);
+ /* convienience methods */
+PHP_METHOD(domdocument, load);
+PHP_FUNCTION(dom_document_save);
+PHP_METHOD(domdocument, loadXML);
+PHP_FUNCTION(dom_document_savexml);
+PHP_FUNCTION(dom_document_validate);
+PHP_FUNCTION(dom_document_xinclude);
+PHP_METHOD(domdocument, registerNodeClass);
+
+#if defined(LIBXML_HTML_ENABLED)
+PHP_METHOD(domdocument, loadHTML);
+PHP_METHOD(domdocument, loadHTMLFile);
+PHP_FUNCTION(dom_document_save_html);
+PHP_FUNCTION(dom_document_save_html_file);
+#endif /* defined(LIBXML_HTML_ENABLED) */
+
+#if defined(LIBXML_SCHEMAS_ENABLED)
+PHP_FUNCTION(dom_document_schema_validate_file);
+PHP_FUNCTION(dom_document_schema_validate_xml);
+PHP_FUNCTION(dom_document_relaxNG_validate_file);
+PHP_FUNCTION(dom_document_relaxNG_validate_xml);
+#endif
+
+/* domnode methods */
+PHP_FUNCTION(dom_node_insert_before);
+PHP_FUNCTION(dom_node_replace_child);
+PHP_FUNCTION(dom_node_remove_child);
+PHP_FUNCTION(dom_node_append_child);
+PHP_FUNCTION(dom_node_has_child_nodes);
+PHP_FUNCTION(dom_node_clone_node);
+PHP_FUNCTION(dom_node_normalize);
+PHP_FUNCTION(dom_node_is_supported);
+PHP_FUNCTION(dom_node_has_attributes);
+PHP_FUNCTION(dom_node_compare_document_position);
+PHP_FUNCTION(dom_node_is_same_node);
+PHP_FUNCTION(dom_node_lookup_prefix);
+PHP_FUNCTION(dom_node_is_default_namespace);
+PHP_FUNCTION(dom_node_lookup_namespace_uri);
+PHP_FUNCTION(dom_node_is_equal_node);
+PHP_FUNCTION(dom_node_get_feature);
+PHP_FUNCTION(dom_node_set_user_data);
+PHP_FUNCTION(dom_node_get_user_data);
+PHP_METHOD(domnode, C14N);
+PHP_METHOD(domnode, C14NFile);
+PHP_METHOD(domnode, getNodePath);
+PHP_METHOD(domnode, getLineNo);
+
+/* domnodelist methods */
+PHP_FUNCTION(dom_nodelist_item);
+
+/* domnamednodemap methods */
+PHP_FUNCTION(dom_namednodemap_get_named_item);
+PHP_FUNCTION(dom_namednodemap_set_named_item);
+PHP_FUNCTION(dom_namednodemap_remove_named_item);
+PHP_FUNCTION(dom_namednodemap_item);
+PHP_FUNCTION(dom_namednodemap_get_named_item_ns);
+PHP_FUNCTION(dom_namednodemap_set_named_item_ns);
+PHP_FUNCTION(dom_namednodemap_remove_named_item_ns);
+
+/* domcharacterdata methods */
+PHP_FUNCTION(dom_characterdata_substring_data);
+PHP_FUNCTION(dom_characterdata_append_data);
+PHP_FUNCTION(dom_characterdata_insert_data);
+PHP_FUNCTION(dom_characterdata_delete_data);
+PHP_FUNCTION(dom_characterdata_replace_data);
+
+/* domattr methods */
+PHP_FUNCTION(dom_attr_is_id);
+PHP_METHOD(domattr, __construct);
+
+/* domelement methods */
+PHP_FUNCTION(dom_element_get_attribute);
+PHP_FUNCTION(dom_element_set_attribute);
+PHP_FUNCTION(dom_element_remove_attribute);
+PHP_FUNCTION(dom_element_get_attribute_node);
+PHP_FUNCTION(dom_element_set_attribute_node);
+PHP_FUNCTION(dom_element_remove_attribute_node);
+PHP_FUNCTION(dom_element_get_elements_by_tag_name);
+PHP_FUNCTION(dom_element_get_attribute_ns);
+PHP_FUNCTION(dom_element_set_attribute_ns);
+PHP_FUNCTION(dom_element_remove_attribute_ns);
+PHP_FUNCTION(dom_element_get_attribute_node_ns);
+PHP_FUNCTION(dom_element_set_attribute_node_ns);
+PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns);
+PHP_FUNCTION(dom_element_has_attribute);
+PHP_FUNCTION(dom_element_has_attribute_ns);
+PHP_FUNCTION(dom_element_set_id_attribute);
+PHP_FUNCTION(dom_element_set_id_attribute_ns);
+PHP_FUNCTION(dom_element_set_id_attribute_node);
+PHP_METHOD(domelement, __construct);
+
+/* domtext methods */
+PHP_FUNCTION(dom_text_split_text);
+PHP_FUNCTION(dom_text_is_whitespace_in_element_content);
+PHP_FUNCTION(dom_text_replace_whole_text);
+PHP_METHOD(domtext, __construct);
+
+/* domcomment methods */
+PHP_METHOD(domcomment, __construct);
+
+/* domtypeinfo methods */
+
+/* domuserdatahandler methods */
+PHP_FUNCTION(dom_userdatahandler_handle);
+
+/* domdomerror methods */
+
+/* domerrorhandler methods */
+PHP_FUNCTION(dom_domerrorhandler_handle_error);
+
+/* domlocator methods */
+
+/* domconfiguration methods */
+PHP_FUNCTION(dom_domconfiguration_set_parameter);
+PHP_FUNCTION(dom_domconfiguration_get_parameter);
+PHP_FUNCTION(dom_domconfiguration_can_set_parameter);
+
+/* domcdatasection methods */
+PHP_METHOD(domcdatasection, __construct);
+
+/* domdocumenttype methods */
+
+/* domnotation methods */
+
+/* domentity methods */
+
+/* domentityreference methods */
+PHP_METHOD(domentityreference, __construct);
+
+/* domprocessinginstruction methods */
+PHP_METHOD(domprocessinginstruction, __construct);
+
+/* string_extend methods */
+PHP_FUNCTION(dom_string_extend_find_offset16);
+PHP_FUNCTION(dom_string_extend_find_offset32);
+
+#if defined(LIBXML_XPATH_ENABLED)
+/* xpath methods */
+PHP_METHOD(domxpath, __construct);
+PHP_FUNCTION(dom_xpath_register_ns);
+PHP_FUNCTION(dom_xpath_query);
+PHP_FUNCTION(dom_xpath_evaluate);
+PHP_FUNCTION(dom_xpath_register_php_functions);
+#endif
+
+#endif /* DOM_FE_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c
new file mode 100644
index 0000000..f4183d2
--- /dev/null
+++ b/ext/dom/dom_iterators.c
@@ -0,0 +1,351 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+#include "dom_ce.h"
+
+typedef struct _nodeIterator nodeIterator;
+struct _nodeIterator {
+ int cur;
+ int index;
+ xmlNode *node;
+};
+
+typedef struct _notationIterator notationIterator;
+struct _notationIterator {
+ int cur;
+ int index;
+ xmlNotation *notation;
+};
+
+static void itemHashScanner (void *payload, void *data, xmlChar *name) /* {{{ */
+{
+ nodeIterator *priv = (nodeIterator *)data;
+
+ if(priv->cur < priv->index) {
+ priv->cur++;
+ } else {
+ if(priv->node == NULL) {
+ priv->node = (xmlNode *)payload;
+ }
+ }
+}
+/* }}} */
+
+xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID) /* {{{ */
+{
+ xmlEntityPtr ret;
+
+ ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
+ memset(ret, 0, sizeof(xmlEntity));
+ ret->type = XML_NOTATION_NODE;
+ ret->name = xmlStrdup(name);
+ ret->ExternalID = xmlStrdup(ExternalID);
+ ret->SystemID = xmlStrdup(SystemID);
+ ret->length = 0;
+ ret->content = NULL;
+ ret->URI = NULL;
+ ret->orig = NULL;
+ ret->children = NULL;
+ ret->parent = NULL;
+ ret->doc = NULL;
+ ret->_private = NULL;
+ ret->last = NULL;
+ ret->prev = NULL;
+ return((xmlNodePtr) ret);
+}
+/* }}} */
+
+xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index) /* {{{ */
+{
+ xmlNode *nodep = NULL;
+ nodeIterator *iter;
+ int htsize;
+
+ if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
+ iter = emalloc(sizeof(nodeIterator));
+ iter->cur = 0;
+ iter->index = index;
+ iter->node = NULL;
+ xmlHashScan(ht, itemHashScanner, iter);
+ nodep = iter->node;
+ efree(iter);
+ return nodep;
+ } else {
+ return NULL;
+ }
+}
+/* }}} */
+
+xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index) /* {{{ */
+{
+ notationIterator *iter;
+ xmlNotation *notep = NULL;
+ int htsize;
+
+ if ((htsize = xmlHashSize(ht)) > 0 && index < htsize) {
+ iter = emalloc(sizeof(notationIterator));
+ iter->cur = 0;
+ iter->index = index;
+ iter->notation = NULL;
+ xmlHashScan(ht, itemHashScanner, iter);
+ notep = iter->notation;
+ efree(iter);
+ return create_notation(notep->name, notep->PublicID, notep->SystemID);
+ } else {
+ return NULL;
+ }
+}
+/* }}} */
+
+static void php_dom_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
+{
+ php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+ zval_ptr_dtor((zval**)&iterator->intern.data);
+
+ if (iterator->curobj) {
+ zval_ptr_dtor((zval**)&iterator->curobj);
+ }
+
+ efree(iterator);
+}
+/* }}} */
+
+static int php_dom_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
+{
+
+ php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+ if (iterator->curobj) {
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+/* }}} */
+
+static void php_dom_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
+{
+ php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+ *data = &iterator->curobj;
+}
+/* }}} */
+
+static int php_dom_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+{
+ zval *curobj;
+ xmlNodePtr curnode = NULL;
+ dom_object *intern;
+ zval *object;
+ int namelen;
+
+ php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+ object = (zval *)iterator->intern.data;
+
+ if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
+ *int_key = iter->index;
+ return HASH_KEY_IS_LONG;
+ } else {
+ curobj = iterator->curobj;
+
+ intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
+ if (intern != NULL && intern->ptr != NULL) {
+ curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
+ } else {
+ return HASH_KEY_NON_EXISTANT;
+ }
+
+ namelen = xmlStrlen(curnode->name);
+ *str_key = estrndup(curnode->name, namelen);
+ *str_key_len = namelen + 1;
+ return HASH_KEY_IS_STRING;
+ }
+}
+/* }}} */
+
+static void php_dom_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
+{
+ zval *curobj, *curattr = NULL;
+ zval *object;
+ xmlNodePtr curnode = NULL, basenode;
+ dom_object *intern;
+ dom_object *nnmap;
+ dom_nnodemap_object *objmap;
+ int ret, previndex=0;
+ HashTable *nodeht;
+ zval **entry;
+
+ php_dom_iterator *iterator = (php_dom_iterator *)iter;
+
+ object = (zval *)iterator->intern.data;
+ nnmap = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
+ objmap = (dom_nnodemap_object *)nnmap->ptr;
+
+ curobj = iterator->curobj;
+ intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
+ if (intern != NULL && intern->ptr != NULL) {
+ if (objmap->nodetype != XML_ENTITY_NODE &&
+ objmap->nodetype != XML_NOTATION_NODE) {
+ if (objmap->nodetype == DOM_NODESET) {
+ nodeht = HASH_OF(objmap->baseobjptr);
+ zend_hash_move_forward(nodeht);
+ if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
+ curattr = *entry;
+ Z_ADDREF_P(curattr);
+ }
+ } else {
+ curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
+ if (objmap->nodetype == XML_ATTRIBUTE_NODE ||
+ objmap->nodetype == XML_ELEMENT_NODE) {
+ curnode = curnode->next;
+ } else {
+ /* Nav the tree evey time as this is LIVE */
+ basenode = dom_object_get_node(objmap->baseobj);
+ if (basenode && (basenode->type == XML_DOCUMENT_NODE ||
+ basenode->type == XML_HTML_DOCUMENT_NODE)) {
+ basenode = xmlDocGetRootElement((xmlDoc *) basenode);
+ } else if (basenode) {
+ basenode = basenode->children;
+ } else {
+ goto err;
+ }
+ curnode = dom_get_elements_by_tag_name_ns_raw(basenode, objmap->ns, objmap->local, &previndex, iter->index);
+ }
+ }
+ } else {
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ curnode = php_dom_libxml_hash_iter(objmap->ht, iter->index);
+ } else {
+ curnode = php_dom_libxml_notation_iter(objmap->ht, iter->index);
+ }
+ }
+ }
+err:
+ zval_ptr_dtor((zval**)&curobj);
+ if (curnode) {
+ MAKE_STD_ZVAL(curattr);
+ curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC);
+ }
+
+ iterator->curobj = curattr;
+}
+/* }}} */
+
+zend_object_iterator_funcs php_dom_iterator_funcs = {
+ php_dom_iterator_dtor,
+ php_dom_iterator_valid,
+ php_dom_iterator_current_data,
+ php_dom_iterator_current_key,
+ php_dom_iterator_move_forward,
+ NULL
+};
+
+zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
+{
+ dom_object *intern;
+ dom_nnodemap_object *objmap;
+ xmlNodePtr nodep, curnode=NULL;
+ zval *curattr = NULL;
+ int ret, curindex = 0;
+ HashTable *nodeht;
+ zval **entry;
+ php_dom_iterator *iterator;
+
+ if (by_ref) {
+ zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
+ }
+ iterator = emalloc(sizeof(php_dom_iterator));
+
+ Z_ADDREF_P(object);
+ iterator->intern.data = (void*)object;
+ iterator->intern.funcs = &php_dom_iterator_funcs;
+
+ intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
+ objmap = (dom_nnodemap_object *)intern->ptr;
+ if (objmap != NULL) {
+ if (objmap->nodetype != XML_ENTITY_NODE &&
+ objmap->nodetype != XML_NOTATION_NODE) {
+ if (objmap->nodetype == DOM_NODESET) {
+ nodeht = HASH_OF(objmap->baseobjptr);
+ zend_hash_internal_pointer_reset(nodeht);
+ if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
+ curattr = *entry;
+ Z_ADDREF_P(curattr);
+ }
+ } else {
+ nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
+ if (!nodep) {
+ goto err;
+ }
+ if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+ if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
+ curnode = (xmlNodePtr) nodep->properties;
+ } else {
+ curnode = (xmlNodePtr) nodep->children;
+ }
+ } else {
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+ } else {
+ nodep = nodep->children;
+ }
+ curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
+ }
+ }
+ } else {
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
+ } else {
+ curnode = php_dom_libxml_notation_iter(objmap->ht, 0);
+ }
+ }
+ }
+err:
+ if (curnode) {
+ MAKE_STD_ZVAL(curattr);
+ curattr = php_dom_create_object(curnode, &ret, curattr, objmap->baseobj TSRMLS_CC);
+ }
+
+ iterator->curobj = curattr;
+
+ return (zend_object_iterator*)iterator;
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h
new file mode 100644
index 0000000..8482502
--- /dev/null
+++ b/ext/dom/dom_properties.h
@@ -0,0 +1,171 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+#ifndef DOM_PROPERTIES_H
+#define DOM_PROPERTIES_H
+
+/* attr properties */
+int dom_attr_name_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_attr_specified_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_attr_value_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_attr_owner_element_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_attr_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* characterdata properties */
+int dom_characterdata_data_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_characterdata_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* document properties */
+int dom_document_doctype_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_implementation_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_document_element_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_document_encoding_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_document_standalone_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_standalone_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_document_version_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_document_strict_error_checking_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_strict_error_checking_write(dom_object *obj, zval *newval TSRMLS_DC);
+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_recover_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_document_recover_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);
+int dom_documenttype_entities_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_documenttype_notations_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_documenttype_public_id_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_documenttype_system_id_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* domerror properties */
+int dom_domerror_severity_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domerror_message_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domerror_type_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domerror_related_exception_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domerror_related_data_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domerror_location_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* domimplementationlist properties */
+int dom_domimplementationlist_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* domlocator properties */
+int dom_domlocator_line_number_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domlocator_column_number_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domlocator_offset_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domlocator_related_node_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_domlocator_uri_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* domstringlist properties */
+int dom_domstringlist_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* element properties */
+int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* entity properties */
+int dom_entity_public_id_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_entity_system_id_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_entity_notation_name_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_entity_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_entity_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_entity_encoding_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_entity_encoding_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_entity_version_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_entity_version_write(dom_object *obj, zval *newval TSRMLS_DC);
+
+/* namednodemap properties */
+int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* namelist properties */
+int dom_namelist_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* node properties */
+int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC);
+int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC);
+
+/* nodelist properties */
+int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* notation properties */
+int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* processinginstruction properties */
+int dom_processinginstruction_target_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_processinginstruction_data_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC);
+
+/* text properties */
+int dom_text_whole_text_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+/* typeinfo properties */
+int dom_typeinfo_type_name_read(dom_object *obj, zval **retval TSRMLS_DC);
+int dom_typeinfo_type_namespace_read(dom_object *obj, zval **retval TSRMLS_DC);
+
+#if defined(LIBXML_XPATH_ENABLED)
+/* xpath properties */
+int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC);
+#endif
+
+#endif /* DOM_PROPERTIERS_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domconfiguration.c b/ext/dom/domconfiguration.c
new file mode 100644
index 0000000..4092d73
--- /dev/null
+++ b/ext/dom/domconfiguration.c
@@ -0,0 +1,103 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_configuration_set_parameter, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_configuration_get_parameter, 0, 0, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_configuration_can_set_parameter, 0, 0, 0)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class domdomconfiguration
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domconfiguration_class_functions[] = {
+ PHP_FALIAS(setParameter, dom_domconfiguration_set_parameter, arginfo_dom_configuration_set_parameter)
+ PHP_FALIAS(getParameter, dom_domconfiguration_get_parameter, arginfo_dom_configuration_get_parameter)
+ PHP_FALIAS(canSetParameter, dom_domconfiguration_can_set_parameter, arginfo_dom_configuration_can_set_parameter)
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ proto dom_void dom_domconfiguration_set_parameter(string name, domuserdata value);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-property
+Since:
+*/
+PHP_FUNCTION(dom_domconfiguration_set_parameter)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domconfiguration_set_parameter */
+
+/* {{{ proto domdomuserdata dom_domconfiguration_get_parameter(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-getParameter
+Since:
+*/
+PHP_FUNCTION(dom_domconfiguration_get_parameter)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domconfiguration_get_parameter */
+
+/* {{{ proto boolean dom_domconfiguration_can_set_parameter(string name, domuserdata value);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMConfiguration-canSetParameter
+Since:
+*/
+PHP_FUNCTION(dom_domconfiguration_can_set_parameter)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domconfiguration_can_set_parameter */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domerror.c b/ext/dom/domerror.c
new file mode 100644
index 0000000..92b6622
--- /dev/null
+++ b/ext/dom/domerror.c
@@ -0,0 +1,139 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/*
+* class domerror
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-Interfaces-DOMError
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domerror_class_functions[] = {
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ severity unsigned short
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-severity
+Since:
+*/
+int dom_domerror_severity_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ message string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-message
+Since:
+*/
+int dom_domerror_message_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ type string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-type
+Since:
+*/
+int dom_domerror_type_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ relatedException object
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-relatedException
+Since:
+*/
+int dom_domerror_related_exception_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ relatedData domobject
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-relatedData
+Since:
+*/
+int dom_domerror_related_data_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ location domlocator
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-DOMError-location
+Since:
+*/
+int dom_domerror_location_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domerrorhandler.c b/ext/dom/domerrorhandler.c
new file mode 100644
index 0000000..7af3723
--- /dev/null
+++ b/ext/dom/domerrorhandler.c
@@ -0,0 +1,71 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_domerrorhandler_handle_error, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, error, DOMDomError, 0)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class domerrorhandler
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ERROR-Interfaces-DOMErrorHandler
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domerrorhandler_class_functions[] = {
+ PHP_FALIAS(handleError, dom_domerrorhandler_handle_error, arginfo_dom_domerrorhandler_handle_error)
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ proto dom_boolean dom_domerrorhandler_handle_error(domerror error);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-ERRORS-DOMErrorHandler-handleError
+Since:
+*/
+PHP_FUNCTION(dom_domerrorhandler_handle_error)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domerrorhandler_handle_error */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c
new file mode 100644
index 0000000..9aa878a
--- /dev/null
+++ b/ext/dom/domexception.c
@@ -0,0 +1,125 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/*
+* class DOMException
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-17189187
+* Since:
+*/
+
+extern zend_class_entry *dom_domexception_class_entry;
+
+const zend_function_entry php_dom_domexception_class_functions[] = {
+ PHP_FE_END
+};
+
+void php_dom_throw_error_with_message(int error_code, char *error_message, int strict_error TSRMLS_DC) /* {{{ */
+{
+ if (strict_error == 1) {
+ zend_throw_exception(dom_domexception_class_entry, error_message, error_code TSRMLS_CC);
+ } else {
+ php_libxml_issue_error(E_WARNING, error_message TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ php_dom_throw_error */
+void php_dom_throw_error(int error_code, int strict_error TSRMLS_DC)
+{
+ char *error_message;
+
+ switch (error_code)
+ {
+ case INDEX_SIZE_ERR:
+ error_message = "Index Size Error";
+ break;
+ case DOMSTRING_SIZE_ERR:
+ error_message = "DOM String Size Error";
+ break;
+ case HIERARCHY_REQUEST_ERR:
+ error_message = "Hierarchy Request Error";
+ break;
+ case WRONG_DOCUMENT_ERR:
+ error_message = "Wrong Document Error";
+ break;
+ case INVALID_CHARACTER_ERR:
+ error_message = "Invalid Character Error";
+ break;
+ case NO_DATA_ALLOWED_ERR:
+ error_message = "No Data Allowed Error";
+ break;
+ case NO_MODIFICATION_ALLOWED_ERR:
+ error_message = "No Modification Allowed Error";
+ break;
+ case NOT_FOUND_ERR:
+ error_message = "Not Found Error";
+ break;
+ case NOT_SUPPORTED_ERR:
+ error_message = "Not Supported Error";
+ break;
+ case INUSE_ATTRIBUTE_ERR:
+ error_message = "Inuse Attribute Error";
+ break;
+ case INVALID_STATE_ERR:
+ error_message = "Invalid State Error";
+ break;
+ case SYNTAX_ERR:
+ error_message = "Syntax Error";
+ break;
+ case INVALID_MODIFICATION_ERR:
+ error_message = "Invalid Modification Error";
+ break;
+ case NAMESPACE_ERR:
+ error_message = "Namespace Error";
+ break;
+ case INVALID_ACCESS_ERR:
+ error_message = "Invalid Access Error";
+ break;
+ case VALIDATION_ERR:
+ error_message = "Validation Error";
+ break;
+ default:
+ error_message = "Unhandled Error";
+ }
+
+ php_dom_throw_error_with_message(error_code, error_message, strict_error TSRMLS_CC);
+}
+/* }}} end php_dom_throw_error */
+
+#endif /* HAVE_LIBXML && HAVE_DOM */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c
new file mode 100644
index 0000000..5a32c60
--- /dev/null
+++ b/ext/dom/domimplementation.c
@@ -0,0 +1,268 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_get_feature, 0, 0, 2)
+ ZEND_ARG_INFO(0, feature)
+ ZEND_ARG_INFO(0, version)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_has_feature, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_documenttype, 0, 0, 3)
+ ZEND_ARG_INFO(0, qualifiedName)
+ ZEND_ARG_INFO(0, publicId)
+ ZEND_ARG_INFO(0, systemId)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementation_create_document, 0, 0, 3)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ ZEND_ARG_OBJ_INFO(0, docType, DOMDocumentType, 0)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMImplementation
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-102161490
+* Since:
+*/
+
+const zend_function_entry php_dom_domimplementation_class_functions[] = {
+ PHP_ME(domimplementation, getFeature, arginfo_dom_implementation_get_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_ME(domimplementation, hasFeature, arginfo_dom_implementation_has_feature, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_ME(domimplementation, createDocumentType, arginfo_dom_implementation_create_documenttype, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_ME(domimplementation, createDocument, arginfo_dom_implementation_create_document, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
+ PHP_FE_END
+};
+
+/* {{{ proto boolean dom_domimplementation_has_feature(string feature, string version);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5CED94D7
+Since:
+*/
+PHP_METHOD(domimplementation, hasFeature)
+{
+ int feature_len, version_len;
+ char *feature, *version;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &feature, &feature_len, &version, &version_len) == FAILURE) {
+ return;
+ }
+
+ if (dom_has_feature(feature, version)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_domimplementation_has_feature */
+
+/* {{{ proto DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType
+Since: DOM Level 2
+*/
+PHP_METHOD(domimplementation, createDocumentType)
+{
+ xmlDtd *doctype;
+ int ret, name_len = 0, publicid_len = 0, systemid_len = 0;
+ char *name = NULL, *publicid = NULL, *systemid = NULL;
+ xmlChar *pch1 = NULL, *pch2 = NULL, *localname = NULL;
+ xmlURIPtr uri;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sss", &name, &name_len, &publicid, &publicid_len, &systemid, &systemid_len) == FAILURE) {
+ return;
+ }
+
+ if (name_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "qualifiedName is required");
+ RETURN_FALSE;
+ }
+
+ if (publicid_len > 0)
+ pch1 = publicid;
+ if (systemid_len > 0)
+ pch2 = systemid;
+
+ uri = xmlParseURI(name);
+ if (uri != NULL && uri->opaque != NULL) {
+ localname = xmlStrdup(uri->opaque);
+ if (xmlStrchr(localname, (xmlChar) ':') != NULL) {
+ php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC);
+ xmlFreeURI(uri);
+ xmlFree(localname);
+ RETURN_FALSE;
+ }
+ } else {
+ localname = xmlStrdup(name);
+ }
+
+ /* TODO: Test that localname has no invalid chars
+ php_dom_throw_error(INVALID_CHARACTER_ERR, TSRMLS_CC);
+ */
+
+ if (uri) {
+ xmlFreeURI(uri);
+ }
+
+ doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2);
+ xmlFree(localname);
+
+ if (doctype == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create DocumentType");
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) doctype, &ret, NULL);
+}
+/* }}} end dom_domimplementation_create_document_type */
+
+/* {{{ proto DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument
+Since: DOM Level 2
+*/
+PHP_METHOD(domimplementation, createDocument)
+{
+ zval *node = NULL;
+ xmlDoc *docp;
+ xmlNode *nodep;
+ xmlDtdPtr doctype = NULL;
+ xmlNsPtr nsptr = NULL;
+ int ret, uri_len = 0, name_len = 0, errorcode = 0;
+ char *uri = NULL, *name = NULL;
+ char *prefix = NULL, *localname = NULL;
+ dom_object *doctobj;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssO", &uri, &uri_len, &name, &name_len, &node, dom_documenttype_class_entry) == FAILURE) {
+ return;
+ }
+
+ if (node != NULL) {
+ DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj);
+ if (doctype->type == XML_DOCUMENT_TYPE_NODE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid DocumentType object");
+ RETURN_FALSE;
+ }
+ if (doctype->doc != NULL) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ } else {
+ doctobj = NULL;
+ }
+
+ if (name_len > 0) {
+ errorcode = dom_check_qname(name, &localname, &prefix, 1, name_len);
+ if (errorcode == 0 && uri_len > 0 && ((nsptr = xmlNewNs(NULL, uri, prefix)) == NULL)) {
+ errorcode = NAMESPACE_ERR;
+ }
+ }
+
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+
+ if (errorcode != 0) {
+ if (localname != NULL) {
+ xmlFree(localname);
+ }
+ php_dom_throw_error(errorcode, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* currently letting libxml2 set the version string */
+ docp = xmlNewDoc(NULL);
+ if (!docp) {
+ if (localname != NULL) {
+ xmlFree(localname);
+ }
+ RETURN_FALSE;
+ }
+
+ if (doctype != NULL) {
+ docp->intSubset = doctype;
+ doctype->parent = docp;
+ doctype->doc = docp;
+ docp->children = (xmlNodePtr) doctype;
+ docp->last = (xmlNodePtr) doctype;
+ }
+
+ if (localname != NULL) {
+ nodep = xmlNewDocNode (docp, nsptr, localname, NULL);
+ if (!nodep) {
+ if (doctype != NULL) {
+ docp->intSubset = NULL;
+ doctype->parent = NULL;
+ doctype->doc = NULL;
+ docp->children = NULL;
+ docp->last = NULL;
+ }
+ xmlFreeDoc(docp);
+ xmlFree(localname);
+ /* Need some type of error here */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected Error");
+ RETURN_FALSE;
+ }
+
+ nodep->nsDef = nsptr;
+
+ xmlDocSetRootElement(docp, nodep);
+ xmlFree(localname);
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) docp, &ret, NULL);
+
+ if (doctobj != NULL) {
+ doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp TSRMLS_CC);
+ }
+}
+/* }}} end dom_domimplementation_create_document */
+
+/* {{{ proto DOMNode dom_domimplementation_get_feature(string feature, string version);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementation3-getFeature
+Since: DOM Level 3
+*/
+PHP_METHOD(domimplementation, getFeature)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domimplementation_get_feature */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domimplementationlist.c b/ext/dom/domimplementationlist.c
new file mode 100644
index 0000000..d89d2ff
--- /dev/null
+++ b/ext/dom/domimplementationlist.c
@@ -0,0 +1,85 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementationlist_item, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class domimplementationlist
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domimplementationlist_class_functions[] = {
+ PHP_FALIAS(item, dom_domimplementationlist_item, arginfo_dom_implementationlist_item)
+ {NULL, NULL, NULL}
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ length unsigned long
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-length
+Since:
+*/
+int dom_domimplementationlist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto domdomimplementation dom_domimplementationlist_item(int index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationList-item
+Since:
+*/
+PHP_FUNCTION(dom_domimplementationlist_item)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domimplementationlist_item */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domimplementationsource.c b/ext/dom/domimplementationsource.c
new file mode 100644
index 0000000..2fb5887
--- /dev/null
+++ b/ext/dom/domimplementationsource.c
@@ -0,0 +1,87 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementationsource_getdomimplementation, 0, 0, 1)
+ ZEND_ARG_INFO(0, features)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_implementationsource_getdomimplementations, 0, 0, 1)
+ ZEND_ARG_INFO(0, features)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class domimplementationsource
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMImplementationSource
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domimplementationsource_class_functions[] = {
+ PHP_FALIAS(getDomimplementation, dom_domimplementationsource_get_domimplementation, arginfo_dom_implementationsource_getdomimplementation)
+ PHP_FALIAS(getDomimplementations, dom_domimplementationsource_get_domimplementations, arginfo_dom_implementationsource_getdomimplementations)
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ proto domdomimplementation dom_domimplementationsource_get_domimplementation(string features);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpl
+Since:
+*/
+PHP_FUNCTION(dom_domimplementationsource_get_domimplementation)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domimplementationsource_get_domimplementation */
+
+/* {{{ proto domimplementationlist dom_domimplementationsource_get_domimplementations(string features);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-getDOMImpls
+Since:
+*/
+PHP_FUNCTION(dom_domimplementationsource_get_domimplementations)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domimplementationsource_get_domimplementations */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domlocator.c b/ext/dom/domlocator.c
new file mode 100644
index 0000000..88c352b
--- /dev/null
+++ b/ext/dom/domlocator.c
@@ -0,0 +1,125 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/*
+* class domlocator
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Interfaces-DOMLocator
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domlocator_class_functions[] = {
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ line_number long
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-line-number
+Since:
+*/
+int dom_domlocator_line_number_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ column_number long
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-column-number
+Since:
+*/
+int dom_domlocator_column_number_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ offset long
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-offset
+Since:
+*/
+int dom_domlocator_offset_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ related_node node
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-node
+Since:
+*/
+int dom_domlocator_related_node_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ uri string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMLocator-uri
+Since:
+*/
+int dom_domlocator_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/domstringlist.c b/ext/dom/domstringlist.c
new file mode 100644
index 0000000..d2ab606
--- /dev/null
+++ b/ext/dom/domstringlist.c
@@ -0,0 +1,85 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_stringlist_item, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class domstringlist
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_domstringlist_class_functions[] = {
+ PHP_FALIAS(item, dom_domstringlist_item, arginfo_dom_stringlist_item)
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ length unsigned long
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-length
+Since:
+*/
+int dom_domstringlist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto domstring dom_domstringlist_item(int index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#DOMStringList-item
+Since:
+*/
+PHP_FUNCTION(dom_domstringlist_item)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_domstringlist_item */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/element.c b/ext/dom/element.c
new file mode 100644
index 0000000..f217ca2
--- /dev/null
+++ b/ext/dom/element.c
@@ -0,0 +1,1254 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_node, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, oldAttr, DOMAttr, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_ns, 0, 0, 3)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, qualifiedName)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_remove_attribute_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_attribute_node_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_attribute_node_ns, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, newAttr, DOMAttr, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_get_elements_by_tag_name_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_has_attribute_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute, 0, 0, 2)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, isId)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_ns, 0, 0, 3)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ ZEND_ARG_INFO(0, isId)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_set_id_attribute_node, 0, 0, 2)
+ ZEND_ARG_OBJ_INFO(0, attr, DOMAttr, 0)
+ ZEND_ARG_INFO(0, isId)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_element_construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ ZEND_ARG_INFO(0, uri)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMElement extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-745549614
+* Since:
+*/
+
+const zend_function_entry php_dom_element_class_functions[] = { /* {{{ */
+ PHP_FALIAS(getAttribute, dom_element_get_attribute, arginfo_dom_element_get_attribute)
+ PHP_FALIAS(setAttribute, dom_element_set_attribute, arginfo_dom_element_set_attribute)
+ PHP_FALIAS(removeAttribute, dom_element_remove_attribute, arginfo_dom_element_remove_attribute)
+ PHP_FALIAS(getAttributeNode, dom_element_get_attribute_node, arginfo_dom_element_get_attribute_node)
+ PHP_FALIAS(setAttributeNode, dom_element_set_attribute_node, arginfo_dom_element_set_attribute_node)
+ PHP_FALIAS(removeAttributeNode, dom_element_remove_attribute_node, arginfo_dom_element_remove_attribute_node)
+ PHP_FALIAS(getElementsByTagName, dom_element_get_elements_by_tag_name, arginfo_dom_element_get_elements_by_tag_name)
+ PHP_FALIAS(getAttributeNS, dom_element_get_attribute_ns, arginfo_dom_element_get_attribute_ns)
+ PHP_FALIAS(setAttributeNS, dom_element_set_attribute_ns, arginfo_dom_element_set_attribute_ns)
+ PHP_FALIAS(removeAttributeNS, dom_element_remove_attribute_ns, arginfo_dom_element_remove_attribute_ns)
+ PHP_FALIAS(getAttributeNodeNS, dom_element_get_attribute_node_ns, arginfo_dom_element_get_attribute_node_ns)
+ PHP_FALIAS(setAttributeNodeNS, dom_element_set_attribute_node_ns, arginfo_dom_element_set_attribute_node_ns)
+ PHP_FALIAS(getElementsByTagNameNS, dom_element_get_elements_by_tag_name_ns, arginfo_dom_element_get_elements_by_tag_name_ns)
+ PHP_FALIAS(hasAttribute, dom_element_has_attribute, arginfo_dom_element_has_attribute)
+ PHP_FALIAS(hasAttributeNS, dom_element_has_attribute_ns, arginfo_dom_element_has_attribute_ns)
+ PHP_FALIAS(setIdAttribute, dom_element_set_id_attribute, arginfo_dom_element_set_id_attribute)
+ PHP_FALIAS(setIdAttributeNS, dom_element_set_id_attribute_ns, arginfo_dom_element_set_id_attribute_ns)
+ PHP_FALIAS(setIdAttributeNode, dom_element_set_id_attribute_node, arginfo_dom_element_set_id_attribute_node)
+ PHP_ME(domelement, __construct, arginfo_dom_element_construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ proto void DOMElement::__construct(string name, [string value], [string uri]); */
+PHP_METHOD(domelement, __construct)
+{
+
+ zval *id;
+ xmlNodePtr nodep = NULL, oldnode = NULL;
+ dom_object *intern;
+ char *name, *value = NULL, *uri = NULL;
+ char *localname = NULL, *prefix = NULL;
+ int errorcode = 0, uri_len = 0;
+ int name_len, value_len = 0, name_valid;
+ xmlNsPtr nsptr = NULL;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s!s", &id, dom_element_class_entry, &name, &name_len, &value, &value_len, &uri, &uri_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+
+ name_valid = xmlValidateName((xmlChar *) name, 0);
+ if (name_valid != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* Namespace logic is seperate and only when uri passed in to insure no BC breakage */
+ if (uri_len > 0) {
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+ if (errorcode == 0) {
+ nodep = xmlNewNode (NULL, (xmlChar *)localname);
+ if (nodep != NULL && uri != NULL) {
+ nsptr = dom_get_ns(nodep, uri, &errorcode, prefix);
+ xmlSetNs(nodep, nsptr);
+ }
+ }
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+ if (errorcode != 0) {
+ if (nodep != NULL) {
+ xmlFreeNode(nodep);
+ }
+ php_dom_throw_error(errorcode, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ } else {
+ /* If you don't pass a namespace uri, then you can't set a prefix */
+ localname = xmlSplitQName2((xmlChar *)name, (xmlChar **) &prefix);
+ if (prefix != NULL) {
+ xmlFree(localname);
+ xmlFree(prefix);
+ php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ nodep = xmlNewNode(NULL, (xmlChar *) name);
+ }
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (value_len > 0) {
+ xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len);
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMElement::__construct */
+
+/* {{{ tagName string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-104682815
+Since:
+*/
+int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr nodep;
+ xmlNsPtr ns;
+ xmlChar *qname;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ ns = nodep->ns;
+ if (ns != NULL && ns->prefix) {
+ qname = xmlStrdup(ns->prefix);
+ qname = xmlStrcat(qname, (xmlChar *)":");
+ qname = xmlStrcat(qname, nodep->name);
+ ZVAL_STRING(*retval, (char *)qname, 1);
+ xmlFree(qname);
+ } else {
+ ZVAL_STRING(*retval, (char *) nodep->name, 1);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ schemaTypeInfo typeinfo
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Element-schemaTypeInfo
+Since: DOM Level 3
+*/
+int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+static xmlNodePtr dom_get_dom1_attribute(xmlNodePtr elem, xmlChar *name) /* {{{ */
+{
+ int len;
+ const xmlChar *nqname;
+
+ nqname = xmlSplitQName3(name, &len);
+ if (nqname != NULL) {
+ xmlNsPtr ns;
+ xmlChar *prefix = xmlStrndup(name, len);
+ if (prefix && xmlStrEqual(prefix, (xmlChar *)"xmlns")) {
+ ns = elem->nsDef;
+ while (ns) {
+ if (xmlStrEqual(ns->prefix, nqname)) {
+ break;
+ }
+ ns = ns->next;
+ }
+ xmlFree(prefix);
+ return (xmlNodePtr)ns;
+ }
+ ns = xmlSearchNs(elem->doc, elem, prefix);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+ if (ns != NULL) {
+ return (xmlNodePtr)xmlHasNsProp(elem, nqname, ns->href);
+ }
+ } else {
+ if (xmlStrEqual(name, (xmlChar *)"xmlns")) {
+ xmlNsPtr nsPtr = elem->nsDef;
+ while (nsPtr) {
+ if (nsPtr->prefix == NULL) {
+ return (xmlNodePtr)nsPtr;
+ }
+ nsPtr = nsPtr->next;
+ }
+ return NULL;
+ }
+ }
+ return (xmlNodePtr)xmlHasNsProp(elem, name, NULL);
+}
+/* }}} */
+
+/* {{{ proto string dom_element_get_attribute(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-666EE0F9
+Since:
+*/
+PHP_FUNCTION(dom_element_get_attribute)
+{
+ zval *id;
+ xmlNode *nodep;
+ char *name;
+ xmlChar *value = NULL;
+ dom_object *intern;
+ xmlNodePtr attr;
+ int name_len;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ if (attr) {
+ switch (attr->type) {
+ case XML_ATTRIBUTE_NODE:
+ value = xmlNodeListGetString(attr->doc, attr->children, 1);
+ break;
+ case XML_NAMESPACE_DECL:
+ value = xmlStrdup(((xmlNsPtr)attr)->href);
+ break;
+ default:
+ value = xmlStrdup(((xmlAttributePtr)attr)->defaultValue);
+ }
+ }
+
+ if (value == NULL) {
+ RETURN_EMPTY_STRING();
+ } else {
+ RETVAL_STRING((char *)value, 1);
+ xmlFree(value);
+ }
+}
+/* }}} end dom_element_get_attribute */
+
+/* {{{ proto void dom_element_set_attribute(string name, string value);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68F082
+Since:
+*/
+PHP_FUNCTION(dom_element_set_attribute)
+{
+ zval *id;
+ xmlNode *nodep;
+ xmlNodePtr attr = NULL;
+ int ret, name_len, value_len, name_valid;
+ dom_object *intern;
+ char *name, *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ if (name_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
+ RETURN_FALSE;
+ }
+
+ name_valid = xmlValidateName((xmlChar *) name, 0);
+ if (name_valid != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ if (attr != NULL) {
+ switch (attr->type) {
+ case XML_ATTRIBUTE_NODE:
+ node_list_unlink(attr->children TSRMLS_CC);
+ break;
+ case XML_NAMESPACE_DECL:
+ RETURN_FALSE;
+ default:
+ break;
+ }
+
+ }
+
+ if (xmlStrEqual((xmlChar *)name, (xmlChar *)"xmlns")) {
+ if (xmlNewNs(nodep, (xmlChar *)value, NULL)) {
+ RETURN_TRUE;
+ }
+ } else {
+ attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, (xmlChar *)value);
+ }
+ if (!attr) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name);
+ RETURN_FALSE;
+ }
+
+ DOM_RET_OBJ(attr, &ret, intern);
+
+}
+/* }}} end dom_element_set_attribute */
+
+/* {{{ proto void dom_element_remove_attribute(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D6AC0F9
+Since:
+*/
+PHP_FUNCTION(dom_element_remove_attribute)
+{
+ zval *id;
+ xmlNodePtr nodep, attrp;
+ dom_object *intern;
+ int name_len;
+ char *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ if (attrp == NULL) {
+ RETURN_FALSE;
+ }
+
+ switch (attrp->type) {
+ case XML_ATTRIBUTE_NODE:
+ if (php_dom_object_get_data(attrp) == NULL) {
+ node_list_unlink(attrp->children TSRMLS_CC);
+ xmlUnlinkNode(attrp);
+ xmlFreeProp((xmlAttrPtr)attrp);
+ } else {
+ xmlUnlinkNode(attrp);
+ }
+ break;
+ case XML_NAMESPACE_DECL:
+ RETURN_FALSE;
+ default:
+ break;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} end dom_element_remove_attribute */
+
+/* {{{ proto DOMAttr dom_element_get_attribute_node(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-217A91B8
+Since:
+*/
+PHP_FUNCTION(dom_element_get_attribute_node)
+{
+ zval *id;
+ xmlNodePtr nodep, attrp;
+ int name_len, ret;
+ dom_object *intern;
+ char *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ if (attrp == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (attrp->type == XML_NAMESPACE_DECL) {
+ xmlNsPtr curns;
+ xmlNodePtr nsparent;
+
+ nsparent = attrp->_private;
+ curns = xmlNewNs(NULL, attrp->name, NULL);
+ if (attrp->children) {
+ curns->prefix = xmlStrdup((xmlChar *) attrp->children);
+ }
+ if (attrp->children) {
+ attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *) attrp->children, attrp->name);
+ } else {
+ attrp = xmlNewDocNode(nodep->doc, NULL, (xmlChar *)"xmlns", attrp->name);
+ }
+ attrp->type = XML_NAMESPACE_DECL;
+ attrp->parent = nsparent;
+ attrp->ns = curns;
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
+}
+/* }}} end dom_element_get_attribute_node */
+
+/* {{{ proto DOMAttr dom_element_set_attribute_node(DOMAttr newAttr);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-887236154
+Since:
+*/
+PHP_FUNCTION(dom_element_set_attribute_node)
+{
+ zval *id, *node;
+ xmlNode *nodep;
+ xmlAttr *attrp, *existattrp = NULL;
+ dom_object *intern, *attrobj, *oldobj;
+ int ret;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
+
+ if (attrp->type != XML_ATTRIBUTE_NODE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required");
+ RETURN_FALSE;
+ }
+
+ if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ existattrp = xmlHasProp(nodep, attrp->name);
+ if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
+ if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
+ ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
+ {
+ RETURN_NULL();
+ }
+ xmlUnlinkNode((xmlNodePtr) existattrp);
+ }
+
+ if (attrp->parent != NULL) {
+ xmlUnlinkNode((xmlNodePtr) attrp);
+ }
+
+ if (attrp->doc == NULL && nodep->doc != NULL) {
+ attrobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
+ }
+
+ xmlAddChild(nodep, (xmlNodePtr) attrp);
+
+ /* Returns old property if removed otherwise NULL */
+ if (existattrp != NULL) {
+ DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern);
+ } else {
+ RETVAL_NULL();
+ }
+
+}
+/* }}} end dom_element_set_attribute_node */
+
+/* {{{ proto DOMAttr dom_element_remove_attribute_node(DOMAttr oldAttr);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D589198
+Since:
+*/
+PHP_FUNCTION(dom_element_remove_attribute_node)
+{
+ zval *id, *node;
+ xmlNode *nodep;
+ xmlAttr *attrp;
+ dom_object *intern, *attrobj;
+ int ret;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
+
+ if (attrp->type != XML_ATTRIBUTE_NODE || attrp->parent != nodep) {
+ php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ xmlUnlinkNode((xmlNodePtr) attrp);
+
+ DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
+
+}
+/* }}} end dom_element_remove_attribute_node */
+
+/* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1938918D
+Since:
+*/
+PHP_FUNCTION(dom_element_get_elements_by_tag_name)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ int name_len;
+ dom_object *intern, *namednode;
+ char *name;
+ xmlChar *local;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ local = xmlCharStrndup(name, name_len);
+ dom_namednode_iter(intern, 0, namednode, NULL, local, NULL TSRMLS_CC);
+}
+/* }}} end dom_element_get_elements_by_tag_name */
+
+/* {{{ proto string dom_element_get_attribute_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAttrNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_get_attribute_ns)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ xmlNsPtr nsptr;
+ dom_object *intern;
+ int uri_len = 0, name_len = 0;
+ char *uri, *name;
+ xmlChar *strattr;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri);
+
+ if (strattr != NULL) {
+ RETVAL_STRING((char *)strattr, 1);
+ xmlFree(strattr);
+ } else {
+ if (xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
+ nsptr = dom_get_nsdecl(elemp, (xmlChar *)name);
+ if (nsptr != NULL) {
+ RETVAL_STRING((char *) nsptr->href, 1);
+ } else {
+ RETVAL_EMPTY_STRING();
+ }
+ } else {
+ RETVAL_EMPTY_STRING();
+ }
+ }
+
+}
+/* }}} end dom_element_get_attribute_ns */
+
+static xmlNsPtr _dom_new_reconNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) /* {{{ */
+{
+ xmlNsPtr def;
+ xmlChar prefix[50];
+ int counter = 1;
+
+ if ((tree == NULL) || (ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
+ return NULL;
+ }
+
+ /* Code taken from libxml2 (2.6.20) xmlNewReconciliedNs
+ *
+ * Find a close prefix which is not already in use.
+ * Let's strip namespace prefixes longer than 20 chars !
+ */
+ if (ns->prefix == NULL)
+ snprintf((char *) prefix, sizeof(prefix), "default");
+ else
+ snprintf((char *) prefix, sizeof(prefix), "%.20s", (char *)ns->prefix);
+
+ def = xmlSearchNs(doc, tree, prefix);
+ while (def != NULL) {
+ if (counter > 1000) return(NULL);
+ if (ns->prefix == NULL)
+ snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
+ else
+ snprintf((char *) prefix, sizeof(prefix), "%.20s%d",
+ (char *)ns->prefix, counter++);
+ def = xmlSearchNs(doc, tree, prefix);
+ }
+
+ /*
+ * OK, now we are ready to create a new one.
+ */
+ def = xmlNewNs(tree, ns->href, prefix);
+ return(def);
+}
+/* }}} */
+
+/* {{{ proto void dom_element_set_attribute_ns(string namespaceURI, string qualifiedName, string value);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAttrNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_set_attribute_ns)
+{
+ zval *id;
+ xmlNodePtr elemp, nodep = NULL;
+ xmlNsPtr nsptr;
+ xmlAttr *attr;
+ int uri_len = 0, name_len = 0, value_len = 0;
+ char *uri, *name, *value;
+ char *localname = NULL, *prefix = NULL;
+ dom_object *intern;
+ int errorcode = 0, stricterror, is_xmlns = 0, name_valid;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!ss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &value, &value_len) == FAILURE) {
+ return;
+ }
+
+ if (name_len == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute Name is required");
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ stricterror = dom_get_strict_error(intern->document);
+
+ if (dom_node_is_read_only(elemp) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len);
+
+ if (errorcode == 0) {
+ if (uri_len > 0) {
+ nodep = (xmlNodePtr) xmlHasNsProp(elemp, (xmlChar *) localname, (xmlChar *) uri);
+ if (nodep != NULL && nodep->type != XML_ATTRIBUTE_DECL) {
+ node_list_unlink(nodep->children TSRMLS_CC);
+ }
+
+ if ((xmlStrEqual((xmlChar *) prefix, (xmlChar *)"xmlns") ||
+ (prefix == NULL && xmlStrEqual((xmlChar *) localname, (xmlChar *)"xmlns"))) &&
+ xmlStrEqual((xmlChar *) uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
+ is_xmlns = 1;
+ if (prefix == NULL) {
+ nsptr = dom_get_nsdecl(elemp, NULL);
+ } else {
+ nsptr = dom_get_nsdecl(elemp, (xmlChar *)localname);
+ }
+ } else {
+ nsptr = xmlSearchNsByHref(elemp->doc, elemp, (xmlChar *)uri);
+ if (nsptr && nsptr->prefix == NULL) {
+ xmlNsPtr tmpnsptr;
+
+ tmpnsptr = nsptr->next;
+ while (tmpnsptr) {
+ if ((tmpnsptr->prefix != NULL) && (tmpnsptr->href != NULL) &&
+ (xmlStrEqual(tmpnsptr->href, (xmlChar *) uri))) {
+ nsptr = tmpnsptr;
+ break;
+ }
+ tmpnsptr = tmpnsptr->next;
+ }
+ if (tmpnsptr == NULL) {
+ nsptr = _dom_new_reconNs(elemp->doc, elemp, nsptr);
+ }
+ }
+ }
+
+ if (nsptr == NULL) {
+ if (prefix == NULL) {
+ if (is_xmlns == 1) {
+ xmlNewNs(elemp, (xmlChar *)value, NULL);
+ xmlReconciliateNs(elemp->doc, elemp);
+ } else {
+ errorcode = NAMESPACE_ERR;
+ }
+ } else {
+ if (is_xmlns == 1) {
+ xmlNewNs(elemp, (xmlChar *)value, (xmlChar *)localname);
+ } else {
+ nsptr = dom_get_ns(elemp, uri, &errorcode, prefix);
+ }
+ xmlReconciliateNs(elemp->doc, elemp);
+ }
+ } else {
+ if (is_xmlns == 1) {
+ if (nsptr->href) {
+ xmlFree((xmlChar *) nsptr->href);
+ }
+ nsptr->href = xmlStrdup((xmlChar *)value);
+ }
+ }
+
+ if (errorcode == 0 && is_xmlns == 0) {
+ xmlSetNsProp(elemp, nsptr, (xmlChar *)localname, (xmlChar *)value);
+ }
+ } else {
+ name_valid = xmlValidateName((xmlChar *) localname, 0);
+ if (name_valid != 0) {
+ errorcode = INVALID_CHARACTER_ERR;
+ stricterror = 1;
+ } else {
+ attr = xmlHasProp(elemp, (xmlChar *)localname);
+ if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) {
+ node_list_unlink(attr->children TSRMLS_CC);
+ }
+ xmlSetProp(elemp, (xmlChar *)localname, (xmlChar *)value);
+ }
+ }
+ }
+
+ xmlFree(localname);
+ if (prefix != NULL) {
+ xmlFree(prefix);
+ }
+
+ if (errorcode != 0) {
+ php_dom_throw_error(errorcode, stricterror TSRMLS_CC);
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_element_set_attribute_ns */
+
+/* {{{ proto void dom_element_remove_attribute_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElRemAtNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_remove_attribute_ns)
+{
+ zval *id;
+ xmlNode *nodep;
+ xmlAttr *attrp;
+ xmlNsPtr nsptr;
+ dom_object *intern;
+ int name_len, uri_len;
+ char *name, *uri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ attrp = xmlHasNsProp(nodep, (xmlChar *)name, (xmlChar *)uri);
+
+ nsptr = dom_get_nsdecl(nodep, (xmlChar *)name);
+ if (nsptr != NULL) {
+ if (xmlStrEqual((xmlChar *)uri, nsptr->href)) {
+ if (nsptr->href != NULL) {
+ xmlFree((char *) nsptr->href);
+ nsptr->href = NULL;
+ }
+ if (nsptr->prefix != NULL) {
+ xmlFree((char *) nsptr->prefix);
+ nsptr->prefix = NULL;
+ }
+ } else {
+ RETURN_NULL();
+ }
+ }
+
+ if (attrp && attrp->type != XML_ATTRIBUTE_DECL) {
+ if (php_dom_object_get_data((xmlNodePtr) attrp) == NULL) {
+ node_list_unlink(attrp->children TSRMLS_CC);
+ xmlUnlinkNode((xmlNodePtr) attrp);
+ xmlFreeProp(attrp);
+ } else {
+ xmlUnlinkNode((xmlNodePtr) attrp);
+ }
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_element_remove_attribute_ns */
+
+/* {{{ proto DOMAttr dom_element_get_attribute_node_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElGetAtNodeNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_get_attribute_node_ns)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ xmlAttrPtr attrp;
+ dom_object *intern;
+ int uri_len, name_len, ret;
+ char *uri, *name;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
+
+ if (attrp == NULL) {
+ RETURN_NULL();
+ }
+
+ DOM_RET_OBJ((xmlNodePtr) attrp, &ret, intern);
+
+}
+/* }}} end dom_element_get_attribute_node_ns */
+
+/* {{{ proto DOMAttr dom_element_set_attribute_node_ns(DOMAttr newAttr);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetAtNodeNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_set_attribute_node_ns)
+{
+ zval *id, *node;
+ xmlNode *nodep;
+ xmlNs *nsp;
+ xmlAttr *attrp, *existattrp = NULL;
+ dom_object *intern, *attrobj, *oldobj;
+ int ret;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_element_class_entry, &node, dom_attr_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
+
+ if (attrp->type != XML_ATTRIBUTE_NODE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute node is required");
+ RETURN_FALSE;
+ }
+
+ if (!(attrp->doc == NULL || attrp->doc == nodep->doc)) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ nsp = attrp->ns;
+ if (nsp != NULL) {
+ existattrp = xmlHasNsProp(nodep, nsp->href, attrp->name);
+ } else {
+ existattrp = xmlHasProp(nodep, attrp->name);
+ }
+
+ if (existattrp != NULL && existattrp->type != XML_ATTRIBUTE_DECL) {
+ if ((oldobj = php_dom_object_get_data((xmlNodePtr) existattrp)) != NULL &&
+ ((php_libxml_node_ptr *)oldobj->ptr)->node == (xmlNodePtr) attrp)
+ {
+ RETURN_NULL();
+ }
+ xmlUnlinkNode((xmlNodePtr) existattrp);
+ }
+
+ if (attrp->parent != NULL) {
+ xmlUnlinkNode((xmlNodePtr) attrp);
+ }
+
+ if (attrp->doc == NULL && nodep->doc != NULL) {
+ attrobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
+ }
+
+ xmlAddChild(nodep, (xmlNodePtr) attrp);
+
+ /* Returns old property if removed otherwise NULL */
+ if (existattrp != NULL) {
+ DOM_RET_OBJ((xmlNodePtr) existattrp, &ret, intern);
+ } else {
+ RETVAL_NULL();
+ }
+
+}
+/* }}} end dom_element_set_attribute_node_ns */
+
+/* {{{ proto DOMNodeList dom_element_get_elements_by_tag_name_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-A6C90942
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_get_elements_by_tag_name_ns)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ int uri_len, name_len;
+ dom_object *intern, *namednode;
+ char *uri, *name;
+ xmlChar *local, *nsuri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ namednode = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ local = xmlCharStrndup(name, name_len);
+ nsuri = xmlCharStrndup(uri, uri_len);
+ dom_namednode_iter(intern, 0, namednode, NULL, local, nsuri TSRMLS_CC);
+
+}
+/* }}} end dom_element_get_elements_by_tag_name_ns */
+
+/* {{{ proto boolean dom_element_has_attribute(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttr
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_has_attribute)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+ char *name;
+ int name_len;
+ xmlNodePtr attr;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_element_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ attr = dom_get_dom1_attribute(nodep, (xmlChar *)name);
+ if (attr == NULL) {
+ RETURN_FALSE;
+ } else {
+ RETURN_TRUE;
+ }
+}
+/* }}} end dom_element_has_attribute */
+
+/* {{{ proto boolean dom_element_has_attribute_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElHasAttrNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_element_has_attribute_ns)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ xmlNs *nsp;
+ dom_object *intern;
+ int uri_len, name_len;
+ char *uri, *name;
+ xmlChar *value;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ value = xmlGetNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
+
+ if (value != NULL) {
+ xmlFree(value);
+ RETURN_TRUE;
+ } else {
+ if (xmlStrEqual((xmlChar *)uri, (xmlChar *)DOM_XMLNS_NAMESPACE)) {
+ nsp = dom_get_nsdecl(elemp, (xmlChar *)name);
+ if (nsp != NULL) {
+ RETURN_TRUE;
+ }
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} end dom_element_has_attribute_ns */
+
+static void php_set_attribute_id(xmlAttrPtr attrp, zend_bool is_id) /* {{{ */
+{
+ if (is_id == 1 && attrp->atype != XML_ATTRIBUTE_ID) {
+ xmlChar *id_val;
+
+ id_val = xmlNodeListGetString(attrp->doc, attrp->children, 1);
+ if (id_val != NULL) {
+ xmlAddID(NULL, attrp->doc, id_val, attrp);
+ xmlFree(id_val);
+ }
+ } else {
+ if (attrp->atype == XML_ATTRIBUTE_ID) {
+ xmlRemoveID(attrp->doc, attrp);
+ attrp->atype = 0;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto void dom_element_set_id_attribute(string name, boolean isId);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttr
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_element_set_id_attribute)
+{
+ zval *id;
+ xmlNode *nodep;
+ xmlAttrPtr attrp;
+ dom_object *intern;
+ char *name;
+ int name_len;
+ zend_bool is_id;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Osb", &id, dom_element_class_entry, &name, &name_len, &is_id) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ attrp = xmlHasNsProp(nodep, (xmlChar *)name, NULL);
+ if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
+ php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ } else {
+ php_set_attribute_id(attrp, is_id);
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_element_set_id_attribute */
+
+/* {{{ proto void dom_element_set_id_attribute_ns(string namespaceURI, string localName, boolean isId);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNS
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_element_set_id_attribute_ns)
+{
+ zval *id;
+ xmlNodePtr elemp;
+ xmlAttrPtr attrp;
+ dom_object *intern;
+ int uri_len, name_len;
+ char *uri, *name;
+ zend_bool is_id;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ossb", &id, dom_element_class_entry, &uri, &uri_len, &name, &name_len, &is_id) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(elemp, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(elemp) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ attrp = xmlHasNsProp(elemp, (xmlChar *)name, (xmlChar *)uri);
+ if (attrp == NULL || attrp->type == XML_ATTRIBUTE_DECL) {
+ php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ } else {
+ php_set_attribute_id(attrp, is_id);
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_element_set_id_attribute_ns */
+
+/* {{{ proto void dom_element_set_id_attribute_node(attr idAttr, boolean isId);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-ElSetIdAttrNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_element_set_id_attribute_node)
+{
+ zval *id, *node;
+ xmlNode *nodep;
+ xmlAttrPtr attrp;
+ dom_object *intern, *attrobj;
+ zend_bool is_id;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OOb", &id, dom_element_class_entry, &node, dom_attr_class_entry, &is_id) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ DOM_GET_OBJ(attrp, node, xmlAttrPtr, attrobj);
+
+ if (attrp->parent != nodep) {
+ php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ } else {
+ php_set_attribute_id(attrp, is_id);
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_element_set_id_attribute_node */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/entity.c b/ext/dom/entity.c
new file mode 100644
index 0000000..18e86fc
--- /dev/null
+++ b/ext/dom/entity.c
@@ -0,0 +1,195 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/*
+* class DOMEntity extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-527DCFF2
+* Since:
+*/
+
+const zend_function_entry php_dom_entity_class_functions[] = {
+ PHP_FE_END
+};
+
+/* {{{ publicId string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-D7303025
+Since:
+*/
+int dom_entity_public_id_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlEntity *nodep;
+
+ nodep = (xmlEntity *) dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+ ZVAL_NULL(*retval);
+ } else {
+ ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ systemId string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-D7C29F3E
+Since:
+*/
+int dom_entity_system_id_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlEntity *nodep;
+
+ nodep = (xmlEntity *) dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+ ZVAL_NULL(*retval);
+ } else {
+ ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ notationName string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-6ABAEB38
+Since:
+*/
+int dom_entity_notation_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlEntity *nodep;
+ char *content;
+
+ nodep = (xmlEntity *) dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (nodep->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
+ ZVAL_NULL(*retval);
+ } else {
+ content = xmlNodeGetContent((xmlNodePtr) nodep);
+ ZVAL_STRING(*retval, content, 1);
+ xmlFree(content);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ actualEncoding string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Entity3-actualEncoding
+Since: DOM Level 3
+*/
+int dom_entity_actual_encoding_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+int dom_entity_actual_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ encoding string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Entity3-encoding
+Since: DOM Level 3
+*/
+int dom_entity_encoding_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+int dom_entity_encoding_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ version string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Entity3-version
+Since: DOM Level 3
+*/
+int dom_entity_version_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+int dom_entity_version_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ return SUCCESS;
+}
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c
new file mode 100644
index 0000000..4ef526c
--- /dev/null
+++ b/ext/dom/entityreference.c
@@ -0,0 +1,100 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_entityreference_construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMEntityReference extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-11C98490
+* Since:
+*/
+
+const zend_function_entry php_dom_entityreference_class_functions[] = {
+ PHP_ME(domentityreference, __construct, arginfo_dom_entityreference_construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* {{{ proto void DOMEntityReference::__construct(string name); */
+PHP_METHOD(domentityreference, __construct)
+{
+ zval *id;
+ xmlNode *node;
+ xmlNodePtr oldnode = NULL;
+ dom_object *intern;
+ char *name;
+ int name_len, name_valid;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_entityreference_class_entry, &name, &name_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+
+ name_valid = xmlValidateName((xmlChar *) name, 0);
+ if (name_valid != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ node = xmlNewReference(NULL, name);
+
+ if (!node) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, node, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMEntityReference::__construct */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/examples/dom1.inc b/ext/dom/examples/dom1.inc
new file mode 100644
index 0000000..792d6f2
--- /dev/null
+++ b/ext/dom/examples/dom1.inc
@@ -0,0 +1,43 @@
+<?PHP
+$xmlstr = "<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE chapter SYSTEM '/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd'
+[ <!ENTITY sp \"spanish\">
+]>
+<!-- lsfj -->
+<chapter language='en'><title language='en'>Title</title>
+<para language='ge'>
+&sp;
+<!-- comment -->
+<informaltable language='&sp;kkk'>
+<tgroup cols='3'>
+<tbody>
+<row><entry>a1</entry><entry morerows='1'>b1</entry><entry>c1</entry></row>
+<row><entry>a2</entry><entry>c2</entry></row>
+<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+</chapter> ";
+
+function print_node($node)
+{
+ print "Node Name: " . $node->nodeName;
+ print "\nNode Type: " . $node->nodeType;
+ $child_count = $node->childNodes->length;
+ print "\nNum Children: " . $child_count;
+ if($child_count <= 1){
+ print "\nNode Content: " . $node->nodeValue;
+ }
+ print "\n\n";
+}
+
+function print_node_list($nodelist)
+{
+ foreach($nodelist as $node)
+ {
+ print_node($node);
+ }
+}
+
+?>
diff --git a/ext/dom/examples/dom1.php b/ext/dom/examples/dom1.php
new file mode 100644
index 0000000..8ea3674
--- /dev/null
+++ b/ext/dom/examples/dom1.php
@@ -0,0 +1,94 @@
+<?php
+require_once("dom1.inc");
+
+echo "Test 1: accessing single nodes from php\n";
+$dom = new domDocument;
+$dom->loadxml($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+// children() of of document would result in a memleak
+//$children = $dom->children();
+//print_node_list($children);
+
+echo "--------- root\n";
+$rootnode = $dom->documentElement;
+print_node($rootnode);
+
+echo "--------- children of root\n";
+$children = $rootnode->childNodes;
+print_node_list($children);
+
+// The last node should be identical with the last entry in the children array
+echo "--------- last\n";
+$last = $rootnode->lastChild;
+print_node($last);
+
+// The parent of this last node is the root again
+echo "--------- parent\n";
+$parent = $last->parentNode;
+print_node($parent);
+
+// The children of this parent are the same children as one above
+echo "--------- children of parent\n";
+$children = $parent->childNodes;
+print_node_list($children);
+
+echo "--------- creating a new attribute\n";
+//This is worthless
+//$attr = $dom->createAttribute("src", "picture.gif");
+//print_r($attr);
+
+//$rootnode->set_attributeNode($attr);
+$attr = $rootnode->setAttribute("src", "picture.gif");
+$attr = $rootnode->getAttribute("src");
+print_r($attr);
+print "\n";
+
+echo "--------- Get Attribute Node\n";
+$attr = $rootnode->getAttributeNode("src");
+print_node($attr);
+
+echo "--------- Remove Attribute Node\n";
+$attr = $rootnode->removeAttribute("src");
+print "Removed " . $attr . " attributes.\n";
+
+echo "--------- attributes of rootnode\n";
+$attrs = $rootnode->attributes;
+print_node_list($attrs);
+
+echo "--------- children of an attribute\n";
+$children = $attrs->item(0)->childNodes;
+print_node_list($children);
+
+echo "--------- Add child to root\n";
+$myelement = new domElement("Silly", "Symphony");
+$newchild = $rootnode->appendChild($myelement);
+print_node($newchild);
+print $dom->saveXML();
+print "\n";
+
+echo "--------- Find element by tagname\n";
+echo " Using dom\n";
+$children = $dom->getElementsByTagname("Silly");
+print_node_list($children);
+
+echo " Using elem\n";
+$children = $rootnode->getElementsByTagName("Silly");
+print_node_list($children);
+
+echo "--------- Unlink Node\n";
+print_node($children->item(0));
+$rootnode->removeChild($children->item(0));
+print_node_list($rootnode->childNodes);
+print $dom->savexml();
+
+echo "--------- Find element by id\n";
+print ("Not implemented\n");
+
+echo "--------- Check various node_name return values\n";
+print ("Not needed\n");
+
+?>
diff --git a/ext/dom/examples/note-invalid.xml b/ext/dom/examples/note-invalid.xml
new file mode 100644
index 0000000..58d4e65
--- /dev/null
+++ b/ext/dom/examples/note-invalid.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE note SYSTEM "note.dtd">
+<note>
+<to>PHP User Group</to>
+<from>Shane</from>
+<heading>Reminder</heading>
+<body>Don't forget the meeting tonight!</body>
+<footer>Or I'll clobber you!</footer>
+</note>
diff --git a/ext/dom/examples/note.dtd b/ext/dom/examples/note.dtd
new file mode 100644
index 0000000..c2d558e
--- /dev/null
+++ b/ext/dom/examples/note.dtd
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!ELEMENT note (to,from,heading,body)>
+<!ELEMENT to (#PCDATA)>
+<!ELEMENT from (#PCDATA)>
+<!ELEMENT heading (#PCDATA)>
+<!ELEMENT body (#PCDATA)>
diff --git a/ext/dom/examples/note.php b/ext/dom/examples/note.php
new file mode 100644
index 0000000..a8695f3
--- /dev/null
+++ b/ext/dom/examples/note.php
@@ -0,0 +1,19 @@
+<?php
+
+$dom = new domDocument;
+$dom->load('note.xml');
+if (!$dom->validate('note.dtd')) {
+ print "Document note.dtd is not valid\n";
+} else {
+ print "Document note.dtd is valid\n";
+}
+
+$dom = new domDocument;
+$dom->load('note-invalid.xml');
+if (!$dom->validate('note.dtd')) {
+ print "Document note-invalid.xml is not valid\n";
+} else {
+ print "Document note-invalid.xml is valid\n";
+}
+
+?>
diff --git a/ext/dom/examples/note.xml b/ext/dom/examples/note.xml
new file mode 100644
index 0000000..49614a1
--- /dev/null
+++ b/ext/dom/examples/note.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE note SYSTEM "note.dtd">
+<note>
+<to>PHP User Group</to>
+<from>Shane</from>
+<heading>Reminder</heading>
+<body>Don't forget the meeting tonight!</body>
+</note>
diff --git a/ext/dom/examples/relaxNG.php b/ext/dom/examples/relaxNG.php
new file mode 100644
index 0000000..d265fd9
--- /dev/null
+++ b/ext/dom/examples/relaxNG.php
@@ -0,0 +1,11 @@
+<?php
+
+$dom = new domDocument;
+$dom->load('relaxNG.xml');
+if (!$dom->relaxNGValidate('relaxNG.rng')) {
+ print "Document is not valid";
+} else {
+ print "Document is valid";
+}
+
+?> \ No newline at end of file
diff --git a/ext/dom/examples/relaxNG.rng b/ext/dom/examples/relaxNG.rng
new file mode 100644
index 0000000..f4357e0
--- /dev/null
+++ b/ext/dom/examples/relaxNG.rng
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+<include href="relaxNG2.rng">
+<define name="TEI.prose"><ref name="INCLUDE"/></define>
+</include>
+</grammar>
+
+
+
diff --git a/ext/dom/examples/relaxNG.xml b/ext/dom/examples/relaxNG.xml
new file mode 100644
index 0000000..6b0cac1
--- /dev/null
+++ b/ext/dom/examples/relaxNG.xml
@@ -0,0 +1 @@
+<TEI.2>hello</TEI.2> \ No newline at end of file
diff --git a/ext/dom/examples/relaxNG2.rng b/ext/dom/examples/relaxNG2.rng
new file mode 100644
index 0000000..4adae7b
--- /dev/null
+++ b/ext/dom/examples/relaxNG2.rng
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:t="http://www.thaiopensource.com/ns/annotations" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <start>
+ <ref name="TEI.2"/>
+ </start>
+ <define name="IGNORE">
+ <notAllowed/>
+ </define>
+ <define name="INCLUDE">
+ <empty/>
+ </define>
+
+
+ <include href="relaxNG3.rng"/>
+
+ <define name="TEI.2">
+ <element name="TEI.2">
+ <text/>
+ </element>
+ </define>
+
+</grammar> \ No newline at end of file
diff --git a/ext/dom/examples/relaxNG3.rng b/ext/dom/examples/relaxNG3.rng
new file mode 100644
index 0000000..73e1eb6
--- /dev/null
+++ b/ext/dom/examples/relaxNG3.rng
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:t="http://www.thaiopensource.com/ns/annotations" xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+ <define name="TEI.prose" combine="interleave">
+ <ref name="IGNORE"/>
+ </define>
+
+</grammar> \ No newline at end of file
diff --git a/ext/dom/examples/shipping.php b/ext/dom/examples/shipping.php
new file mode 100644
index 0000000..5205fd2
--- /dev/null
+++ b/ext/dom/examples/shipping.php
@@ -0,0 +1,11 @@
+<?php
+
+$dom = new domDocument;
+$dom->load('shipping.xml');
+if (!$dom->schemaValidate('shipping.xsd')) {
+ print "Document is not valid";
+} else {
+ print "Document is valid";
+}
+
+?> \ No newline at end of file
diff --git a/ext/dom/examples/shipping.xml b/ext/dom/examples/shipping.xml
new file mode 100644
index 0000000..dc8a09e
--- /dev/null
+++ b/ext/dom/examples/shipping.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<shipOrder>
+ <shipTo>
+ <name>Tove Svendson</name>
+ <street>Ragnhildvei 2</street>
+ <address>4000 Stavanger</address>
+ <country>Norway</country>
+ </shipTo>
+ <items>
+ <item>
+ <title>Empire Burlesque</title>
+ <quantity>1</quantity>
+ <price>10.90</price>
+ </item>
+ <item>
+ <title>Hide your heart</title>
+ <quantity>1</quantity>
+ <price>9.90</price>
+ </item>
+ </items>
+</shipOrder> \ No newline at end of file
diff --git a/ext/dom/examples/shipping.xsd b/ext/dom/examples/shipping.xsd
new file mode 100644
index 0000000..8b16b7c
--- /dev/null
+++ b/ext/dom/examples/shipping.xsd
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:element name="shipOrder" type="order"/>
+
+ <xsd:complexType name="order">
+ <xsd:all>
+ <xsd:element name="shipTo" type="shipAddress"/>
+ <xsd:element name="items" type="cdItems"/>
+ </xsd:all>
+ </xsd:complexType>
+
+ <xsd:complexType name="shipAddress">
+ <xsd:all>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="street" type="xsd:string"/>
+ <xsd:element name="address" type="xsd:string"/>
+ <xsd:element name="country" type="xsd:string"/>
+ </xsd:all>
+ </xsd:complexType>
+
+ <xsd:complexType name="cdItems">
+ <xsd:sequence>
+ <xsd:element name="item" type="cdItem" maxOccurs="unbounded" minOccurs="1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="cdItem">
+ <xsd:all>
+ <xsd:element name="title" type="xsd:string"/>
+ <xsd:element name="quantity" type="xsd:positiveInteger"/>
+ <xsd:element name="price" type="xsd:decimal"/>
+ </xsd:all>
+ </xsd:complexType>
+
+</xsd:schema> \ No newline at end of file
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
new file mode 100644
index 0000000..07d7c70
--- /dev/null
+++ b/ext/dom/namednodemap.c
@@ -0,0 +1,338 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_get_named_item, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_set_named_item, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item, 0, 0, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_item, 0, 0, 0)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_get_named_item_ns, 0, 0, 0)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_set_named_item_ns, 0, 0, 0)
+ ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namednodemap_remove_named_item_ns, 0, 0, 0)
+ ZEND_ARG_INFO(0, namespaceURI)
+ ZEND_ARG_INFO(0, localName)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMNamedNodeMap
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1780488922
+* Since:
+*/
+
+const zend_function_entry php_dom_namednodemap_class_functions[] = { /* {{{ */
+ PHP_FALIAS(getNamedItem, dom_namednodemap_get_named_item, arginfo_dom_namednodemap_get_named_item)
+ PHP_FALIAS(setNamedItem, dom_namednodemap_set_named_item, arginfo_dom_namednodemap_set_named_item)
+ PHP_FALIAS(removeNamedItem, dom_namednodemap_remove_named_item, arginfo_dom_namednodemap_remove_named_item)
+ PHP_FALIAS(item, dom_namednodemap_item, arginfo_dom_namednodemap_item)
+ PHP_FALIAS(getNamedItemNS, dom_namednodemap_get_named_item_ns, arginfo_dom_namednodemap_get_named_item_ns)
+ PHP_FALIAS(setNamedItemNS, dom_namednodemap_set_named_item_ns, arginfo_dom_namednodemap_set_named_item_ns)
+ PHP_FALIAS(removeNamedItemNS, dom_namednodemap_remove_named_item_ns, arginfo_dom_namednodemap_remove_named_item_ns)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ length int
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6D0FB19E
+Since:
+*/
+int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_nnodemap_object *objmap;
+ xmlAttrPtr curnode;
+ xmlNodePtr nodep;
+ int count = 0;
+
+ objmap = (dom_nnodemap_object *)obj->ptr;
+
+ if (objmap != NULL) {
+ if ((objmap->nodetype == XML_NOTATION_NODE) ||
+ objmap->nodetype == XML_ENTITY_NODE) {
+ if (objmap->ht) {
+ count = xmlHashSize(objmap->ht);
+ }
+ } else {
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ curnode = nodep->properties;
+ if (curnode) {
+ count++;
+ while (curnode->next != NULL) {
+ count++;
+ curnode = curnode->next;
+ }
+ }
+ }
+ }
+ }
+
+ MAKE_STD_ZVAL(*retval);
+ ZVAL_LONG(*retval, count);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto DOMNode dom_namednodemap_get_named_item(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1074577549
+Since:
+*/
+PHP_FUNCTION(dom_namednodemap_get_named_item)
+{
+ zval *id;
+ int ret, namedlen=0;
+ dom_object *intern;
+ xmlNodePtr itemnode = NULL;
+ char *named;
+
+ dom_nnodemap_object *objmap;
+ xmlNodePtr nodep;
+ xmlNotation *notep = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_namednodemap_class_entry, &named, &namedlen) == FAILURE) {
+ return;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ objmap = (dom_nnodemap_object *)intern->ptr;
+
+ if (objmap != NULL) {
+ if ((objmap->nodetype == XML_NOTATION_NODE) ||
+ objmap->nodetype == XML_ENTITY_NODE) {
+ if (objmap->ht) {
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+ } else {
+ notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+ if (notep) {
+ itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+ }
+ }
+ }
+ } else {
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
+ }
+ }
+ }
+
+ if (itemnode) {
+ DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
+ return;
+ } else {
+ RETVAL_NULL();
+ }
+}
+/* }}} end dom_namednodemap_get_named_item */
+
+/* {{{ proto DOMNode dom_namednodemap_set_named_item(DOMNode arg);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1025163788
+Since:
+*/
+PHP_FUNCTION(dom_namednodemap_set_named_item)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_namednodemap_set_named_item */
+
+/* {{{ proto DOMNode dom_namednodemap_remove_named_item(string name);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-D58B193
+Since:
+*/
+PHP_FUNCTION(dom_namednodemap_remove_named_item)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_namednodemap_remove_named_item */
+
+/* {{{ proto DOMNode dom_namednodemap_item(int index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-349467F9
+Since:
+*/
+PHP_FUNCTION(dom_namednodemap_item)
+{
+ zval *id;
+ long index;
+ int ret;
+ dom_object *intern;
+ xmlNodePtr itemnode = NULL;
+
+ dom_nnodemap_object *objmap;
+ xmlNodePtr nodep, curnode;
+ int count;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_namednodemap_class_entry, &index) == FAILURE) {
+ return;
+ }
+ if (index >= 0) {
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ objmap = (dom_nnodemap_object *)intern->ptr;
+
+ if (objmap != NULL) {
+ if ((objmap->nodetype == XML_NOTATION_NODE) ||
+ objmap->nodetype == XML_ENTITY_NODE) {
+ if (objmap->ht) {
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+ } else {
+ itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+ }
+ }
+ } else {
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ curnode = (xmlNodePtr)nodep->properties;
+ count = 0;
+ while (count < index && curnode != NULL) {
+ count++;
+ curnode = (xmlNodePtr)curnode->next;
+ }
+ itemnode = curnode;
+ }
+ }
+ }
+
+ if (itemnode) {
+ DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
+ return;
+ }
+ }
+
+ RETVAL_NULL();
+}
+/* }}} end dom_namednodemap_item */
+
+/* {{{ proto DOMNode dom_namednodemap_get_named_item_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-getNamedItemNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_namednodemap_get_named_item_ns)
+{
+ zval *id;
+ int ret, namedlen=0, urilen=0;
+ dom_object *intern;
+ xmlNodePtr itemnode = NULL;
+ char *uri, *named;
+
+ dom_nnodemap_object *objmap;
+ xmlNodePtr nodep;
+ xmlNotation *notep = NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!s", &id, dom_namednodemap_class_entry, &uri, &urilen, &named, &namedlen) == FAILURE) {
+ return;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ objmap = (dom_nnodemap_object *)intern->ptr;
+
+ if (objmap != NULL) {
+ if ((objmap->nodetype == XML_NOTATION_NODE) ||
+ objmap->nodetype == XML_ENTITY_NODE) {
+ if (objmap->ht) {
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+ } else {
+ notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+ if (notep) {
+ itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+ }
+ }
+ }
+ } else {
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
+ }
+ }
+ }
+
+ if (itemnode) {
+ DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
+ return;
+ } else {
+ RETVAL_NULL();
+ }
+}
+/* }}} end dom_namednodemap_get_named_item_ns */
+
+/* {{{ proto DOMNode dom_namednodemap_set_named_item_ns(DOMNode arg);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-setNamedItemNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_namednodemap_set_named_item_ns)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_namednodemap_set_named_item_ns */
+
+/* {{{ proto DOMNode dom_namednodemap_remove_named_item_ns(string namespaceURI, string localName);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-removeNamedItemNS
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_namednodemap_remove_named_item_ns)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_namednodemap_remove_named_item_ns */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/namelist.c b/ext/dom/namelist.c
new file mode 100644
index 0000000..5831dde
--- /dev/null
+++ b/ext/dom/namelist.c
@@ -0,0 +1,96 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namelist_get_name, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_namelist_get_namespace_uri, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMNameList
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_namelist_class_functions[] = {
+ PHP_FALIAS(getName, dom_namelist_get_name, arginfo_dom_namelist_get_name)
+ PHP_FALIAS(getNamespaceURI, dom_namelist_get_namespace_uri, arginfo_dom_namelist_get_namespace_uri)
+ PHP_FE_END
+};
+
+/* {{{ length int
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-length
+Since:
+*/
+int dom_namelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, "TEST", 1);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto string dom_namelist_get_name(int index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getName
+Since:
+*/
+PHP_FUNCTION(dom_namelist_get_name)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_namelist_get_name */
+
+/* {{{ proto string dom_namelist_get_namespace_uri(int index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#NameList-getNamespaceURI
+Since:
+*/
+PHP_FUNCTION(dom_namelist_get_namespace_uri)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_namelist_get_namespace_uri */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/node.c b/ext/dom/node.c
new file mode 100644
index 0000000..3279567
--- /dev/null
+++ b/ext/dom/node.c
@@ -0,0 +1,1990 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_insert_before, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
+ ZEND_ARG_OBJ_INFO(0, refChild, DOMNode, 1)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_replace_child, 0, 0, 2)
+ ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
+ ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_remove_child, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, oldChild, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_append_child, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, newChild, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_child_nodes, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_clone_node, 0, 0, 1)
+ ZEND_ARG_INFO(0, deep)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_normalize, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_supported, 0, 0, 2)
+ ZEND_ARG_INFO(0, feature)
+ ZEND_ARG_INFO(0, version)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_has_attributes, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_compare_document_position, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_same_node, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, other, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_prefix, 0, 0, 1)
+ ZEND_ARG_INFO(0, namespaceURI)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_default_namespace, 0, 0, 1)
+ ZEND_ARG_INFO(0, namespaceURI)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_lookup_namespace_uri, 0, 0, 1)
+ ZEND_ARG_INFO(0, prefix)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_is_equal_node, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, arg, DOMNode, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_feature, 0, 0, 2)
+ ZEND_ARG_INFO(0, feature)
+ ZEND_ARG_INFO(0, version)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_set_user_data, 0, 0, 3)
+ ZEND_ARG_INFO(0, key)
+ ZEND_ARG_INFO(0, data)
+ ZEND_ARG_INFO(0, handler)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_get_user_data, 0, 0, 1)
+ ZEND_ARG_INFO(0, key)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getNodePath, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_getLineNo, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14N, 0, 0, 0)
+ ZEND_ARG_INFO(0, exclusive)
+ ZEND_ARG_INFO(0, with_comments)
+ ZEND_ARG_ARRAY_INFO(0, xpath, 1)
+ ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_node_C14NFile, 0, 0, 1)
+ ZEND_ARG_INFO(0, uri)
+ ZEND_ARG_INFO(0, exclusive)
+ ZEND_ARG_INFO(0, with_comments)
+ ZEND_ARG_ARRAY_INFO(0, xpath, 1)
+ ZEND_ARG_ARRAY_INFO(0, ns_prefixes, 1)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1950641247
+* Since:
+*/
+
+const zend_function_entry php_dom_node_class_functions[] = { /* {{{ */
+ PHP_FALIAS(insertBefore, dom_node_insert_before, arginfo_dom_node_insert_before)
+ PHP_FALIAS(replaceChild, dom_node_replace_child, arginfo_dom_node_replace_child)
+ PHP_FALIAS(removeChild, dom_node_remove_child, arginfo_dom_node_remove_child)
+ PHP_FALIAS(appendChild, dom_node_append_child, arginfo_dom_node_append_child)
+ PHP_FALIAS(hasChildNodes, dom_node_has_child_nodes, arginfo_dom_node_has_child_nodes)
+ PHP_FALIAS(cloneNode, dom_node_clone_node, arginfo_dom_node_clone_node)
+ PHP_FALIAS(normalize, dom_node_normalize, arginfo_dom_node_normalize)
+ PHP_FALIAS(isSupported, dom_node_is_supported, arginfo_dom_node_is_supported)
+ PHP_FALIAS(hasAttributes, dom_node_has_attributes, arginfo_dom_node_has_attributes)
+ PHP_FALIAS(compareDocumentPosition, dom_node_compare_document_position, arginfo_dom_node_compare_document_position)
+ PHP_FALIAS(isSameNode, dom_node_is_same_node, arginfo_dom_node_is_same_node)
+ PHP_FALIAS(lookupPrefix, dom_node_lookup_prefix, arginfo_dom_node_lookup_prefix)
+ PHP_FALIAS(isDefaultNamespace, dom_node_is_default_namespace, arginfo_dom_node_is_default_namespace)
+ PHP_FALIAS(lookupNamespaceUri, dom_node_lookup_namespace_uri, arginfo_dom_node_lookup_namespace_uri)
+ PHP_FALIAS(isEqualNode, dom_node_is_equal_node, arginfo_dom_node_is_equal_node)
+ PHP_FALIAS(getFeature, dom_node_get_feature, arginfo_dom_node_get_feature)
+ PHP_FALIAS(setUserData, dom_node_set_user_data, arginfo_dom_node_set_user_data)
+ PHP_FALIAS(getUserData, dom_node_get_user_data, arginfo_dom_node_get_user_data)
+ PHP_ME(domnode, getNodePath, arginfo_dom_node_getNodePath, ZEND_ACC_PUBLIC)
+ PHP_ME(domnode, getLineNo, arginfo_dom_node_getLineNo, ZEND_ACC_PUBLIC)
+ PHP_ME(domnode, C14N, arginfo_dom_node_C14N, ZEND_ACC_PUBLIC)
+ PHP_ME(domnode, C14NFile, arginfo_dom_node_C14NFile, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+static void dom_reconcile_ns(xmlDocPtr doc, xmlNodePtr nodep) /* {{{ */
+{
+ xmlNsPtr nsptr, nsdftptr, curns, prevns = NULL;
+
+ if (nodep->type == XML_ELEMENT_NODE) {
+ /* Following if block primarily used for inserting nodes created via createElementNS */
+ if (nodep->nsDef != NULL) {
+ curns = nodep->nsDef;
+ while (curns) {
+ nsdftptr = curns->next;
+ if (curns->href != NULL) {
+ if((nsptr = xmlSearchNsByHref(doc, nodep->parent, curns->href)) &&
+ (curns->prefix == NULL || xmlStrEqual(nsptr->prefix, curns->prefix))) {
+ curns->next = NULL;
+ if (prevns == NULL) {
+ nodep->nsDef = nsdftptr;
+ } else {
+ prevns->next = nsdftptr;
+ }
+ dom_set_old_ns(doc, curns);
+ curns = prevns;
+ }
+ }
+ prevns = curns;
+ curns = nsdftptr;
+ }
+ }
+ xmlReconciliateNs(doc, nodep);
+ }
+}
+/* }}} */
+
+/* {{{ nodeName string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D095
+Since:
+*/
+int dom_node_node_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ xmlNsPtr ns;
+ char *str = NULL;
+ xmlChar *qname = NULL;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ switch (nodep->type) {
+ case XML_ATTRIBUTE_NODE:
+ case XML_ELEMENT_NODE:
+ ns = nodep->ns;
+ if (ns != NULL && ns->prefix) {
+ qname = xmlStrdup(ns->prefix);
+ qname = xmlStrcat(qname, ":");
+ qname = xmlStrcat(qname, nodep->name);
+ str = qname;
+ } else {
+ str = (char *) nodep->name;
+ }
+ break;
+ case XML_NAMESPACE_DECL:
+ ns = nodep->ns;
+ if (ns != NULL && ns->prefix) {
+ qname = xmlStrdup("xmlns");
+ qname = xmlStrcat(qname, ":");
+ qname = xmlStrcat(qname, nodep->name);
+ str = qname;
+ } else {
+ str = (char *) nodep->name;
+ }
+ break;
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DTD_NODE:
+ case XML_PI_NODE:
+ case XML_ENTITY_DECL:
+ case XML_ENTITY_REF_NODE:
+ case XML_NOTATION_NODE:
+ str = (char *) nodep->name;
+ break;
+ case XML_CDATA_SECTION_NODE:
+ str = "#cdata-section";
+ break;
+ case XML_COMMENT_NODE:
+ str = "#comment";
+ break;
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DOCUMENT_NODE:
+ str = "#document";
+ break;
+ case XML_DOCUMENT_FRAG_NODE:
+ str = "#document-fragment";
+ break;
+ case XML_TEXT_NODE:
+ str = "#text";
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Node Type");
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if(str != NULL) {
+ ZVAL_STRING(*retval, str, 1);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ if (qname != NULL) {
+ xmlFree(qname);
+ }
+
+ return SUCCESS;
+
+}
+
+/* }}} */
+
+/* {{{ nodeValue string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-F68D080
+Since:
+*/
+int dom_node_node_value_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ char *str = NULL;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ /* Access to Element node is implemented as a convience method */
+ switch (nodep->type) {
+ case XML_ATTRIBUTE_NODE:
+ case XML_TEXT_NODE:
+ case XML_ELEMENT_NODE:
+ case XML_COMMENT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_PI_NODE:
+ str = xmlNodeGetContent(nodep);
+ break;
+ case XML_NAMESPACE_DECL:
+ str = xmlNodeGetContent(nodep->children);
+ break;
+ default:
+ str = NULL;
+ break;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if(str != NULL) {
+ ZVAL_STRING(*retval, str, 1);
+ xmlFree(str);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+
+ return SUCCESS;
+
+}
+
+int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ zval value_copy;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ /* Access to Element node is implemented as a convience method */
+ switch (nodep->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ if (nodep->children) {
+ node_list_unlink(nodep->children TSRMLS_CC);
+ }
+ case XML_TEXT_NODE:
+ case XML_COMMENT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_PI_NODE:
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+ xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ nodeType int
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-111237558
+Since:
+*/
+int dom_node_node_type_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ /* Specs dictate that they are both type XML_DOCUMENT_TYPE_NODE */
+ if (nodep->type == XML_DTD_NODE) {
+ ZVAL_LONG(*retval, XML_DOCUMENT_TYPE_NODE);
+ } else {
+ ZVAL_LONG(*retval, nodep->type);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ parentNode DomNode
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1060184317
+Since:
+*/
+int dom_node_parent_node_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep, *nodeparent;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ nodeparent = nodep->parent;
+ if (!nodeparent) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(nodeparent, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ childNodes DomNodeList
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1451460987
+Since:
+*/
+int dom_node_child_nodes_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ dom_object *intern;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (dom_node_children_valid(nodep) == FAILURE) {
+ ZVAL_NULL(*retval);
+ } else {
+ php_dom_create_interator(*retval, DOM_NODELIST TSRMLS_CC);
+ intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+ dom_namednode_iter(obj, XML_ELEMENT_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ firstChild DomNode
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-169727388
+Since:
+*/
+int dom_node_first_child_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep, *first = NULL;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (dom_node_children_valid(nodep) == SUCCESS) {
+ first = nodep->children;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (!first) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(first, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ lastChild DomNode
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-61AD09FB
+Since:
+*/
+int dom_node_last_child_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep, *last = NULL;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (dom_node_children_valid(nodep) == SUCCESS) {
+ last = nodep->last;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (!last) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(last, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ previousSibling DomNode
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-640FB3C8
+Since:
+*/
+int dom_node_previous_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep, *prevsib;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ prevsib = nodep->prev;
+ if (!prevsib) {
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ if (NULL == (*retval = php_dom_create_object(prevsib, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ nextSibling DomNode
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-6AC54C2F
+Since:
+*/
+int dom_node_next_sibling_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep, *nextsib;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ nextsib = nodep->next;
+ if (!nextsib) {
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (NULL == (*retval = php_dom_create_object(nextsib, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ attributes DomNamedNodeMap
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-84CF096
+Since:
+*/
+int dom_node_attributes_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ dom_object *intern;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (nodep->type == XML_ELEMENT_NODE) {
+ php_dom_create_interator(*retval, DOM_NAMEDNODEMAP TSRMLS_CC);
+ intern = (dom_object *)zend_objects_get_address(*retval TSRMLS_CC);
+ dom_namednode_iter(obj, XML_ATTRIBUTE_NODE, intern, NULL, NULL, NULL TSRMLS_CC);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ ownerDocument DomDocument
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-node-ownerDoc
+Since:
+*/
+int dom_node_owner_document_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ xmlDocPtr docp;
+ int ret;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+ }
+
+ docp = nodep->doc;
+ if (!docp) {
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ namespaceUri string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSname
+Since: DOM Level 2
+*/
+int dom_node_namespace_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ char *str = NULL;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ switch (nodep->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ case XML_NAMESPACE_DECL:
+ if (nodep->ns != NULL) {
+ str = (char *) nodep->ns->href;
+ }
+ break;
+ default:
+ str = NULL;
+ break;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if(str != NULL) {
+ ZVAL_STRING(*retval, str, 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ prefix string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSPrefix
+Since: DOM Level 2
+*/
+int dom_node_prefix_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ xmlNsPtr ns;
+ char *str = NULL;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ switch (nodep->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ATTRIBUTE_NODE:
+ case XML_NAMESPACE_DECL:
+ ns = nodep->ns;
+ if (ns != NULL && ns->prefix) {
+ str = (char *) ns->prefix;
+ }
+ break;
+ default:
+ str = NULL;
+ break;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (str == NULL) {
+ ZVAL_EMPTY_STRING(*retval);
+ } else {
+ ZVAL_STRING(*retval, str, 1);
+ }
+ return SUCCESS;
+
+}
+
+int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlNode *nodep, *nsnode = NULL;
+ xmlNsPtr ns = NULL, curns;
+ char *strURI;
+ char *prefix;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ switch (nodep->type) {
+ case XML_ELEMENT_NODE:
+ nsnode = nodep;
+ case XML_ATTRIBUTE_NODE:
+ if (nsnode == NULL) {
+ nsnode = nodep->parent;
+ if (nsnode == NULL) {
+ nsnode = xmlDocGetRootElement(nodep->doc);
+ }
+ }
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+ prefix = Z_STRVAL_P(newval);
+ if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) {
+ strURI = (char *) nodep->ns->href;
+ if (strURI == NULL ||
+ (!strcmp (prefix, "xml") && strcmp(strURI, XML_XML_NAMESPACE)) ||
+ (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (prefix, "xmlns") &&
+ strcmp (strURI, DOM_XMLNS_NAMESPACE)) ||
+ (nodep->type == XML_ATTRIBUTE_NODE && !strcmp (nodep->name, "xmlns"))) {
+ ns = NULL;
+ } else {
+ curns = nsnode->nsDef;
+ while (curns != NULL) {
+ if (xmlStrEqual((xmlChar *)prefix, curns->prefix) && xmlStrEqual(nodep->ns->href, curns->href)) {
+ ns = curns;
+ break;
+ }
+ curns = curns->next;
+ }
+ if (ns == NULL) {
+ ns = xmlNewNs(nsnode, nodep->ns->href, (xmlChar *)prefix);
+ }
+ }
+
+ if (ns == NULL) {
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+ php_dom_throw_error(NAMESPACE_ERR, dom_get_strict_error(obj->document) TSRMLS_CC);
+ return FAILURE;
+ }
+
+ xmlSetNs(nodep, ns);
+ }
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ localName string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeNSLocalN
+Since: DOM Level 2
+*/
+int dom_node_local_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ if (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE || nodep->type == XML_NAMESPACE_DECL) {
+ ZVAL_STRING(*retval, (char *) (nodep->name), 1);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ baseURI string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-baseURI
+Since: DOM Level 3
+*/
+int dom_node_base_uri_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ xmlChar *baseuri;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+ baseuri = xmlNodeGetBase(nodep->doc, nodep);
+ if (baseuri) {
+ ZVAL_STRING(*retval, (char *) (baseuri), 1);
+ xmlFree(baseuri);
+ } else {
+ ZVAL_NULL(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ textContent string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-textContent
+Since: DOM Level 3
+*/
+int dom_node_text_content_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNode *nodep;
+ char *str = NULL;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ str = xmlNodeGetContent(nodep);
+
+ ALLOC_ZVAL(*retval);
+
+ if(str != NULL) {
+ ZVAL_STRING(*retval, str, 1);
+ xmlFree(str);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_node_text_content_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ return SUCCESS;
+}
+
+/* }}} */
+
+static xmlNodePtr _php_dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlNodePtr nextsib, xmlNodePtr fragment, dom_object *intern, dom_object *childobj TSRMLS_DC) /* {{{ */
+{
+ xmlNodePtr newchild, node;
+
+ newchild = fragment->children;
+
+ if (newchild) {
+ if (prevsib == NULL) {
+ nodep->children = newchild;
+ } else {
+ prevsib->next = newchild;
+ }
+ newchild->prev = prevsib;
+ if (nextsib == NULL) {
+ nodep->last = fragment->last;
+ } else {
+ fragment->last->next = nextsib;
+ nextsib->prev = fragment->last;
+ }
+
+ node = newchild;
+ while (node != NULL) {
+ node->parent = nodep;
+ if (node->doc != nodep->doc) {
+ xmlSetTreeDoc(node, nodep->doc);
+ if (node->_private != NULL) {
+ childobj = node->_private;
+ childobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
+ }
+ }
+ if (node == fragment->last) {
+ break;
+ }
+ node = node->next;
+ }
+
+ fragment->children = NULL;
+ fragment->last = NULL;
+ }
+
+ return newchild;
+}
+/* }}} */
+
+/* {{{ proto domnode dom_node_insert_before(DomNode newChild, DomNode refChild);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-952280727
+Since:
+*/
+PHP_FUNCTION(dom_node_insert_before)
+{
+ zval *id, *node, *ref = NULL;
+ xmlNodePtr child, new_child, parentp, refp;
+ dom_object *intern, *childobj, *refpobj;
+ int ret, stricterror;
+
+ 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) {
+ return;
+ }
+
+ DOM_GET_OBJ(parentp, id, xmlNodePtr, intern);
+
+ if (dom_node_children_valid(parentp) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
+
+ new_child = NULL;
+
+ stricterror = dom_get_strict_error(intern->document);
+
+ if (dom_node_is_read_only(parentp) == SUCCESS ||
+ (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (dom_hierarchy(parentp, child) == FAILURE) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (child->doc != parentp->doc && child->doc != NULL) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
+ RETURN_FALSE;
+ }
+
+ if (child->doc == NULL && parentp->doc != NULL) {
+ childobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
+ }
+
+ if (ref != NULL) {
+ DOM_GET_OBJ(refp, ref, xmlNodePtr, refpobj);
+ if (refp->parent != parentp) {
+ php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (child->parent != NULL) {
+ xmlUnlinkNode(child);
+ }
+
+ if (child->type == XML_TEXT_NODE && (refp->type == XML_TEXT_NODE ||
+ (refp->prev != NULL && refp->prev->type == XML_TEXT_NODE))) {
+ if (child->doc == NULL) {
+ xmlSetTreeDoc(child, parentp->doc);
+ }
+ new_child = child;
+ new_child->parent = refp->parent;
+ new_child->next = refp;
+ new_child->prev = refp->prev;
+ refp->prev = new_child;
+ if (new_child->prev != NULL) {
+ new_child->prev->next = new_child;
+ }
+ if (new_child->parent != NULL) {
+ if (new_child->parent->children == refp) {
+ new_child->parent->children = new_child;
+ }
+ }
+
+ } else if (child->type == XML_ATTRIBUTE_NODE) {
+ xmlAttrPtr lastattr;
+
+ if (child->ns == NULL)
+ lastattr = xmlHasProp(refp->parent, child->name);
+ else
+ lastattr = xmlHasNsProp(refp->parent, child->name, child->ns->href);
+ if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
+ if (lastattr != (xmlAttrPtr) child) {
+ xmlUnlinkNode((xmlNodePtr) lastattr);
+ php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
+ } else {
+ DOM_RET_OBJ(child, &ret, intern);
+ return;
+ }
+ }
+ } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
+ new_child = _php_dom_insert_fragment(parentp, refp->prev, refp, child, intern, childobj TSRMLS_CC);
+ }
+
+ if (new_child == NULL) {
+ new_child = xmlAddPrevSibling(refp, child);
+ }
+ } else {
+ if (child->parent != NULL){
+ xmlUnlinkNode(child);
+ }
+ if (child->type == XML_TEXT_NODE && parentp->last != NULL && parentp->last->type == XML_TEXT_NODE) {
+ child->parent = parentp;
+ if (child->doc == NULL) {
+ xmlSetTreeDoc(child, parentp->doc);
+ }
+ new_child = child;
+ if (parentp->children == NULL) {
+ parentp->children = child;
+ parentp->last = child;
+ } else {
+ child = parentp->last;
+ child->next = new_child;
+ new_child->prev = child;
+ parentp->last = new_child;
+ }
+ } else if (child->type == XML_ATTRIBUTE_NODE) {
+ xmlAttrPtr lastattr;
+
+ if (child->ns == NULL)
+ lastattr = xmlHasProp(parentp, child->name);
+ else
+ lastattr = xmlHasNsProp(parentp, child->name, child->ns->href);
+ if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
+ if (lastattr != (xmlAttrPtr) child) {
+ xmlUnlinkNode((xmlNodePtr) lastattr);
+ php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
+ } else {
+ DOM_RET_OBJ(child, &ret, intern);
+ return;
+ }
+ }
+ } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
+ new_child = _php_dom_insert_fragment(parentp, parentp->last, NULL, child, intern, childobj TSRMLS_CC);
+ }
+ if (new_child == NULL) {
+ new_child = xmlAddChild(parentp, child);
+ }
+ }
+
+ if (NULL == new_child) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't add newnode as the previous sibling of refnode");
+ RETURN_FALSE;
+ }
+
+ dom_reconcile_ns(parentp->doc, new_child);
+
+ DOM_RET_OBJ(new_child, &ret, intern);
+
+}
+/* }}} end dom_node_insert_before */
+
+/* {{{ proto DomNode dom_node_replace_child(DomNode newChild, DomNode oldChild);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-785887307
+Since:
+*/
+PHP_FUNCTION(dom_node_replace_child)
+{
+ zval *id, *newnode, *oldnode;
+ xmlNodePtr children, newchild, oldchild, nodep;
+ dom_object *intern, *newchildobj, *oldchildobj;
+ int foundoldchild = 0, stricterror;
+
+ int ret;
+
+ 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) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_children_valid(nodep) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(newchild, newnode, xmlNodePtr, newchildobj);
+ DOM_GET_OBJ(oldchild, oldnode, xmlNodePtr, oldchildobj);
+
+ children = nodep->children;
+ if (!children) {
+ RETURN_FALSE;
+ }
+
+ stricterror = dom_get_strict_error(intern->document);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS ||
+ (newchild->parent != NULL && dom_node_is_read_only(newchild->parent) == SUCCESS)) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (newchild->doc != nodep->doc && newchild->doc != NULL) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (dom_hierarchy(nodep, newchild) == FAILURE) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* check for the old child and whether the new child is already a child */
+ while (children) {
+ if (children == oldchild) {
+ foundoldchild = 1;
+ break;
+ }
+ children = children->next;
+ }
+
+ if (foundoldchild) {
+ if (newchild->type == XML_DOCUMENT_FRAG_NODE) {
+ xmlNodePtr prevsib, nextsib;
+ prevsib = oldchild->prev;
+ nextsib = oldchild->next;
+
+ xmlUnlinkNode(oldchild);
+
+ newchild = _php_dom_insert_fragment(nodep, prevsib, nextsib, newchild, intern, newchildobj TSRMLS_CC);
+ if (newchild) {
+ dom_reconcile_ns(nodep->doc, newchild);
+ }
+ } else if (oldchild != newchild) {
+ if (newchild->doc == NULL && nodep->doc != NULL) {
+ xmlSetTreeDoc(newchild, nodep->doc);
+ newchildobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)newchildobj, NULL TSRMLS_CC);
+ }
+ xmlReplaceNode(oldchild, newchild);
+ dom_reconcile_ns(nodep->doc, newchild);
+ }
+ DOM_RET_OBJ(oldchild, &ret, intern);
+ return;
+ } else {
+ php_dom_throw_error(NOT_FOUND_ERR, dom_get_strict_error(intern->document) TSRMLS_CC);
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_node_replace_child */
+
+/* {{{ proto DomNode dom_node_remove_child(DomNode oldChild);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-1734834066
+Since:
+*/
+PHP_FUNCTION(dom_node_remove_child)
+{
+ zval *id, *node;
+ xmlNodePtr children, child, nodep;
+ dom_object *intern, *childobj;
+ int ret, stricterror;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_children_valid(nodep) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
+
+ stricterror = dom_get_strict_error(intern->document);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS ||
+ (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ children = nodep->children;
+ if (!children) {
+ php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ while (children) {
+ if (children == child) {
+ xmlUnlinkNode(child);
+ DOM_RET_OBJ(child, &ret, intern);
+ return;
+ }
+ children = children->next;
+ }
+
+ php_dom_throw_error(NOT_FOUND_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE
+}
+/* }}} end dom_node_remove_child */
+
+/* {{{ proto DomNode dom_node_append_child(DomNode newChild);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-184E7107
+Since:
+*/
+PHP_FUNCTION(dom_node_append_child)
+{
+ zval *id, *node;
+ xmlNodePtr child, nodep, new_child = NULL;
+ dom_object *intern, *childobj;
+ int ret, stricterror;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_children_valid(nodep) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ DOM_GET_OBJ(child, node, xmlNodePtr, childobj);
+
+ stricterror = dom_get_strict_error(intern->document);
+
+ if (dom_node_is_read_only(nodep) == SUCCESS ||
+ (child->parent != NULL && dom_node_is_read_only(child->parent) == SUCCESS)) {
+ php_dom_throw_error(NO_MODIFICATION_ALLOWED_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (dom_hierarchy(nodep, child) == FAILURE) {
+ php_dom_throw_error(HIERARCHY_REQUEST_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (!(child->doc == NULL || child->doc == nodep->doc)) {
+ php_dom_throw_error(WRONG_DOCUMENT_ERR, stricterror TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (child->type == XML_DOCUMENT_FRAG_NODE && child->children == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document Fragment is empty");
+ RETURN_FALSE;
+ }
+
+ if (child->doc == NULL && nodep->doc != NULL) {
+ childobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)childobj, NULL TSRMLS_CC);
+ }
+
+ if (child->parent != NULL){
+ xmlUnlinkNode(child);
+ }
+
+ if (child->type == XML_TEXT_NODE && nodep->last != NULL && nodep->last->type == XML_TEXT_NODE) {
+ child->parent = nodep;
+ if (child->doc == NULL) {
+ xmlSetTreeDoc(child, nodep->doc);
+ }
+ new_child = child;
+ if (nodep->children == NULL) {
+ nodep->children = child;
+ nodep->last = child;
+ } else {
+ child = nodep->last;
+ child->next = new_child;
+ new_child->prev = child;
+ nodep->last = new_child;
+ }
+ } else if (child->type == XML_ATTRIBUTE_NODE) {
+ xmlAttrPtr lastattr;
+
+ if (child->ns == NULL)
+ lastattr = xmlHasProp(nodep, child->name);
+ else
+ lastattr = xmlHasNsProp(nodep, child->name, child->ns->href);
+ if (lastattr != NULL && lastattr->type != XML_ATTRIBUTE_DECL) {
+ if (lastattr != (xmlAttrPtr) child) {
+ xmlUnlinkNode((xmlNodePtr) lastattr);
+ php_libxml_node_free_resource((xmlNodePtr) lastattr TSRMLS_CC);
+ }
+ }
+ } else if (child->type == XML_DOCUMENT_FRAG_NODE) {
+ new_child = _php_dom_insert_fragment(nodep, nodep->last, NULL, child, intern, childobj TSRMLS_CC);
+ }
+
+ if (new_child == NULL) {
+ new_child = xmlAddChild(nodep, child);
+ if (new_child == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't append node");
+ RETURN_FALSE;
+ }
+ }
+
+ dom_reconcile_ns(nodep->doc, new_child);
+
+ DOM_RET_OBJ(new_child, &ret, intern);
+}
+/* }}} end dom_node_append_child */
+
+/* {{{ proto boolean dom_node_has_child_nodes();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-810594187
+Since:
+*/
+PHP_FUNCTION(dom_node_has_child_nodes)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (dom_node_children_valid(nodep) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (nodep->children) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_node_has_child_nodes */
+
+/* {{{ proto DomNode dom_node_clone_node(boolean deep);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-3A0ED0A4
+Since:
+*/
+PHP_FUNCTION(dom_node_clone_node)
+{
+ zval *id;
+ xmlNode *n, *node;
+ int ret;
+ dom_object *intern;
+ long recursive = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &id, dom_node_class_entry, &recursive) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(n, id, xmlNodePtr, intern);
+
+ node = xmlDocCopyNode(n, n->doc, recursive);
+
+ if (!node) {
+ RETURN_FALSE;
+ }
+
+ /* When deep is false Element nodes still require the attributes
+ Following taken from libxml as xmlDocCopyNode doesnt do this */
+ if (n->type == XML_ELEMENT_NODE && recursive == 0) {
+ if (n->nsDef != NULL) {
+ node->nsDef = xmlCopyNamespaceList(n->nsDef);
+ }
+ if (n->ns != NULL) {
+ xmlNsPtr ns;
+ ns = xmlSearchNs(n->doc, node, n->ns->prefix);
+ if (ns == NULL) {
+ ns = xmlSearchNs(n->doc, n, n->ns->prefix);
+ if (ns != NULL) {
+ xmlNodePtr root = node;
+
+ while (root->parent != NULL) {
+ root = root->parent;
+ }
+ node->ns = xmlNewNs(root, ns->href, ns->prefix);
+ }
+ } else {
+ node->ns = ns;
+ }
+ }
+ if (n->properties != NULL) {
+ node->properties = xmlCopyPropList(node, n->properties);
+ }
+ }
+
+ /* If document cloned we want a new document proxy */
+ if (node->doc != n->doc) {
+ intern = NULL;
+ }
+
+ DOM_RET_OBJ(node, &ret, intern);
+}
+/* }}} end dom_node_clone_node */
+
+/* {{{ proto void dom_node_normalize();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-normalize
+Since:
+*/
+PHP_FUNCTION(dom_node_normalize)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ dom_normalize(nodep TSRMLS_CC);
+
+}
+/* }}} end dom_node_normalize */
+
+/* {{{ proto boolean dom_node_is_supported(string feature, string version);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Level-2-Core-Node-supports
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_node_is_supported)
+{
+ zval *id;
+ int feature_len, version_len;
+ char *feature, *version;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_node_class_entry, &feature, &feature_len, &version, &version_len) == FAILURE) {
+ return;
+ }
+
+ if (dom_has_feature(feature, version)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_node_is_supported */
+
+/* {{{ proto boolean dom_node_has_attributes();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-NodeHasAttrs
+Since: DOM Level 2
+*/
+PHP_FUNCTION(dom_node_has_attributes)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_node_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (nodep->type != XML_ELEMENT_NODE)
+ RETURN_FALSE;
+
+ if (nodep->properties) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_node_has_attributes */
+
+/* {{{ proto short dom_node_compare_document_position(DomNode other);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-compareDocumentPosition
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_compare_document_position)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_node_compare_document_position */
+
+/* {{{ proto boolean dom_node_is_same_node(DomNode other);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isSameNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_is_same_node)
+{
+ zval *id, *node;
+ xmlNodePtr nodeotherp, nodep;
+ dom_object *intern, *nodeotherobj;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_node_class_entry, &node, dom_node_class_entry) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ DOM_GET_OBJ(nodeotherp, node, xmlNodePtr, nodeotherobj);
+
+ if (nodep == nodeotherp) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_node_is_same_node */
+
+/* {{{ proto string dom_node_lookup_prefix(string namespaceURI);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-lookupNamespacePrefix
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_lookup_prefix)
+{
+ zval *id;
+ xmlNodePtr nodep, lookupp = NULL;
+ dom_object *intern;
+ xmlNsPtr nsptr;
+ int uri_len = 0;
+ char *uri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ if (uri_len > 0) {
+ switch (nodep->type) {
+ case XML_ELEMENT_NODE:
+ lookupp = nodep;
+ break;
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ lookupp = xmlDocGetRootElement((xmlDocPtr) nodep);
+ break;
+ case XML_ENTITY_NODE :
+ case XML_NOTATION_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DTD_NODE:
+ RETURN_NULL();
+ break;
+ default:
+ lookupp = nodep->parent;
+ }
+
+ if (lookupp != NULL && (nsptr = xmlSearchNsByHref(lookupp->doc, lookupp, uri))) {
+ if (nsptr->prefix != NULL) {
+ RETURN_STRING((char *) nsptr->prefix, 1);
+ }
+ }
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_node_lookup_prefix */
+
+/* {{{ proto boolean dom_node_is_default_namespace(string namespaceURI);
+URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_is_default_namespace)
+{
+ zval *id;
+ xmlNodePtr nodep;
+ dom_object *intern;
+ xmlNsPtr nsptr;
+ int uri_len = 0;
+ char *uri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_node_class_entry, &uri, &uri_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
+ }
+
+ if (nodep && uri_len > 0) {
+ nsptr = xmlSearchNs(nodep->doc, nodep, NULL);
+ if (nsptr && xmlStrEqual(nsptr->href, uri)) {
+ RETURN_TRUE;
+ }
+ }
+
+ RETURN_FALSE;
+}
+/* }}} end dom_node_is_default_namespace */
+
+/* {{{ proto string dom_node_lookup_namespace_uri(string prefix);
+URL: http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_lookup_namespace_uri)
+{
+ zval *id;
+ xmlNodePtr nodep;
+ dom_object *intern;
+ xmlNsPtr nsptr;
+ int prefix_len = 0;
+ char *prefix=NULL;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os!", &id, dom_node_class_entry, &prefix, &prefix_len) == FAILURE) {
+ return;
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDocPtr) nodep);
+ if (nodep == NULL) {
+ RETURN_NULL();
+ }
+ }
+
+ nsptr = xmlSearchNs(nodep->doc, nodep, prefix);
+ if (nsptr && nsptr->href != NULL) {
+ RETURN_STRING((char *) nsptr->href, 1);
+ }
+
+ RETURN_NULL();
+}
+/* }}} end dom_node_lookup_namespace_uri */
+
+/* {{{ proto boolean dom_node_is_equal_node(DomNode arg);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-isEqualNode
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_is_equal_node)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_node_is_equal_node */
+
+/* {{{ proto DomNode dom_node_get_feature(string feature, string version);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getFeature
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_get_feature)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_node_get_feature */
+
+/* {{{ proto mixed dom_node_set_user_data(string key, mixed data, userdatahandler handler);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-setUserData
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_set_user_data)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_node_set_user_data */
+
+/* {{{ proto mixed dom_node_get_user_data(string key);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Node3-getUserData
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_node_get_user_data)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_node_get_user_data */
+
+static void dom_canonicalization(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
+{
+ zval *id;
+ zval *xpath_array=NULL, *ns_prefixes=NULL;
+ xmlNodePtr nodep;
+ xmlDocPtr docp;
+ xmlNodeSetPtr nodeset = NULL;
+ dom_object *intern;
+ zend_bool exclusive=0, with_comments=0;
+ xmlChar **inclusive_ns_prefixes = NULL;
+ char *file = NULL;
+ int ret = -1, file_len = 0;
+ xmlOutputBufferPtr buf;
+ xmlXPathContextPtr ctxp=NULL;
+ xmlXPathObjectPtr xpathobjp=NULL;
+
+ if (mode == 0) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O|bba!a!", &id, dom_node_class_entry, &exclusive, &with_comments,
+ &xpath_array, &ns_prefixes) == FAILURE) {
+ return;
+ }
+ } else {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Os|bba!a!", &id, dom_node_class_entry, &file, &file_len, &exclusive,
+ &with_comments, &xpath_array, &ns_prefixes) == FAILURE) {
+ return;
+ }
+ }
+
+ DOM_GET_OBJ(nodep, id, xmlNodePtr, intern);
+
+ docp = nodep->doc;
+
+ if (! docp) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node must be associated with a document");
+ RETURN_FALSE;
+ }
+
+ if (xpath_array == NULL) {
+ if (nodep->type != XML_DOCUMENT_NODE) {
+ ctxp = xmlXPathNewContext(docp);
+ ctxp->node = nodep;
+ xpathobjp = xmlXPathEvalExpression("(.//. | .//@* | .//namespace::*)", ctxp);
+ ctxp->node = NULL;
+ if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
+ nodeset = xpathobjp->nodesetval;
+ } else {
+ if (xpathobjp) {
+ xmlXPathFreeObject(xpathobjp);
+ }
+ xmlXPathFreeContext(ctxp);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
+ RETURN_FALSE;
+ }
+ }
+ } else {
+ /*xpath query from xpath_array */
+ HashTable *ht = Z_ARRVAL_P(xpath_array);
+ zval **tmp;
+ char *xquery;
+
+ if (zend_hash_find(ht, "query", sizeof("query"), (void**)&tmp) == SUCCESS &&
+ Z_TYPE_PP(tmp) == IS_STRING) {
+ xquery = Z_STRVAL_PP(tmp);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "'query' missing from xpath array or is not a string");
+ RETURN_FALSE;
+ }
+
+ ctxp = xmlXPathNewContext(docp);
+ ctxp->node = nodep;
+
+ if (zend_hash_find(ht, "namespaces", sizeof("namespaces"), (void**)&tmp) == SUCCESS &&
+ Z_TYPE_PP(tmp) == IS_ARRAY) {
+ zval **tmpns;
+ while (zend_hash_get_current_data(Z_ARRVAL_PP(tmp), (void **)&tmpns) == SUCCESS) {
+ if (Z_TYPE_PP(tmpns) == IS_STRING) {
+ char *prefix;
+ ulong idx;
+ uint prefix_key_len;
+
+ if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(tmp),
+ &prefix, &prefix_key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) {
+ xmlXPathRegisterNs(ctxp, prefix, Z_STRVAL_PP(tmpns));
+ }
+ }
+ zend_hash_move_forward(Z_ARRVAL_PP(tmp));
+ }
+ }
+
+ xpathobjp = xmlXPathEvalExpression(xquery, ctxp);
+ ctxp->node = NULL;
+ if (xpathobjp && xpathobjp->type == XPATH_NODESET) {
+ nodeset = xpathobjp->nodesetval;
+ } else {
+ if (xpathobjp) {
+ xmlXPathFreeObject(xpathobjp);
+ }
+ xmlXPathFreeContext(ctxp);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "XPath query did not return a nodeset.");
+ RETURN_FALSE;
+ }
+ }
+
+ if (ns_prefixes != NULL) {
+ if (exclusive) {
+ zval **tmpns;
+ int nscount = 0;
+
+ inclusive_ns_prefixes = safe_emalloc(zend_hash_num_elements(Z_ARRVAL_P(ns_prefixes)) + 1,
+ sizeof(xmlChar *), 0);
+ while (zend_hash_get_current_data(Z_ARRVAL_P(ns_prefixes), (void **)&tmpns) == SUCCESS) {
+ if (Z_TYPE_PP(tmpns) == IS_STRING) {
+ inclusive_ns_prefixes[nscount++] = Z_STRVAL_PP(tmpns);
+ }
+ zend_hash_move_forward(Z_ARRVAL_P(ns_prefixes));
+ }
+ inclusive_ns_prefixes[nscount] = NULL;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE,
+ "Inclusive namespace prefixes only allowed in exclusive mode.");
+ }
+ }
+
+ if (mode == 1) {
+ buf = xmlOutputBufferCreateFilename(file, NULL, 0);
+ } else {
+ buf = xmlAllocOutputBuffer(NULL);
+ }
+
+ if (buf != NULL) {
+ ret = xmlC14NDocSaveTo(docp, nodeset, exclusive, inclusive_ns_prefixes,
+ with_comments, buf);
+ }
+
+ if (inclusive_ns_prefixes != NULL) {
+ efree(inclusive_ns_prefixes);
+ }
+ if (xpathobjp != NULL) {
+ xmlXPathFreeObject(xpathobjp);
+ }
+ if (ctxp != NULL) {
+ xmlXPathFreeContext(ctxp);
+ }
+
+ if (buf == NULL || ret < 0) {
+ RETVAL_FALSE;
+ } else {
+ if (mode == 0) {
+#ifdef LIBXML2_NEW_BUFFER
+ ret = xmlOutputBufferGetSize(buf);
+#else
+ ret = buf->buffer->use;
+#endif
+ if (ret > 0) {
+#ifdef LIBXML2_NEW_BUFFER
+ RETVAL_STRINGL((char *) xmlOutputBufferGetContent(buf), ret, 1);
+#else
+ RETVAL_STRINGL((char *) buf->buffer->content, ret, 1);
+#endif
+ } else {
+ RETVAL_EMPTY_STRING();
+ }
+ }
+ }
+
+ if (buf) {
+ int bytes;
+
+ bytes = xmlOutputBufferClose(buf);
+ if (mode == 1 && (ret >= 0)) {
+ RETURN_LONG(bytes);
+ }
+ }
+}
+/* }}} */
+
+/* {{{ proto string DOMNode::C14N([bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
+ Canonicalize nodes to a string */
+PHP_METHOD(domnode, C14N)
+{
+ dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto int DOMNode::C14NFile(string uri [, bool exclusive [, bool with_comments [, array xpath [, array ns_prefixes]]]])
+ Canonicalize nodes to a file */
+PHP_METHOD(domnode, C14NFile)
+{
+ dom_canonicalization(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto int DOMNode::getNodePath()
+ Gets an xpath for a node */
+PHP_METHOD(domnode, getNodePath)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+ char *value;
+
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
+
+ value = xmlGetNodePath(nodep);
+ if (value == NULL) {
+ RETURN_NULL();
+ } else {
+ RETVAL_STRING(value, 1);
+ xmlFree(value);
+ }
+}
+/* }}} */
+
+/* {{{ proto int DOMNode::getLineNo()
+ Gets line number for a node */
+PHP_METHOD(domnode, getLineNo)
+{
+ zval *id;
+ xmlNode *nodep;
+ dom_object *intern;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ DOM_GET_THIS_OBJ(nodep, id, xmlNodePtr, intern);
+
+ RETURN_LONG(xmlGetLineNo(nodep));
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c
new file mode 100644
index 0000000..d856f14
--- /dev/null
+++ b/ext/dom/nodelist.c
@@ -0,0 +1,184 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_nodelist_item, 0, 0, 1)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMNodeList
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-536297177
+* Since:
+*/
+
+const zend_function_entry php_dom_nodelist_class_functions[] = {
+ PHP_FALIAS(item, dom_nodelist_item, arginfo_dom_nodelist_item)
+ PHP_FE_END
+};
+
+/* {{{ length int
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-203510337
+Since:
+*/
+int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ dom_nnodemap_object *objmap;
+ xmlNodePtr nodep, curnode;
+ int count = 0;
+ HashTable *nodeht;
+
+ objmap = (dom_nnodemap_object *)obj->ptr;
+ if (objmap != NULL) {
+ if (objmap->ht) {
+ count = xmlHashSize(objmap->ht);
+ } else {
+ if (objmap->nodetype == DOM_NODESET) {
+ nodeht = HASH_OF(objmap->baseobjptr);
+ count = zend_hash_num_elements(nodeht);
+ } else {
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+ curnode = nodep->children;
+ if (curnode) {
+ count++;
+ while (curnode->next != NULL) {
+ count++;
+ curnode = curnode->next;
+ }
+ }
+ } else {
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+ } else {
+ nodep = nodep->children;
+ }
+ curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1);
+ }
+ }
+ }
+ }
+ }
+
+ MAKE_STD_ZVAL(*retval);
+ ZVAL_LONG(*retval, count);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto DOMNode dom_nodelist_item(int index);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-844377136
+Since:
+*/
+PHP_FUNCTION(dom_nodelist_item)
+{
+ zval *id;
+ long index;
+ int ret;
+ dom_object *intern;
+ xmlNodePtr itemnode = NULL;
+
+ dom_nnodemap_object *objmap;
+ xmlNodePtr nodep, curnode;
+ int count = 0;
+ HashTable *nodeht;
+ zval **entry;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_nodelist_class_entry, &index) == FAILURE) {
+ return;
+ }
+
+ if (index >= 0) {
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ objmap = (dom_nnodemap_object *)intern->ptr;
+ if (objmap != NULL) {
+ if (objmap->ht) {
+ if (objmap->nodetype == XML_ENTITY_NODE) {
+ itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+ } else {
+ itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+ }
+ } else {
+ if (objmap->nodetype == DOM_NODESET) {
+ nodeht = HASH_OF(objmap->baseobjptr);
+ if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) {
+ *return_value = **entry;
+ zval_copy_ctor(return_value);
+ return;
+ }
+ } else if (objmap->baseobj) {
+ nodep = dom_object_get_node(objmap->baseobj);
+ if (nodep) {
+ if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+ curnode = nodep->children;
+ while (count < index && curnode != NULL) {
+ count++;
+ curnode = curnode->next;
+ }
+ itemnode = curnode;
+ } else {
+ if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+ nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+ } else {
+ nodep = nodep->children;
+ }
+ itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
+ }
+ }
+ }
+ }
+ }
+
+ if (itemnode) {
+ DOM_RET_OBJ(itemnode, &ret, objmap->baseobj);
+ return;
+ }
+ }
+
+ RETVAL_NULL();
+}
+/* }}} end dom_nodelist_item */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/notation.c b/ext/dom/notation.c
new file mode 100644
index 0000000..1fdfe89
--- /dev/null
+++ b/ext/dom/notation.c
@@ -0,0 +1,110 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/*
+* class DOMNotation extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-5431D1B9
+* Since:
+*/
+
+const zend_function_entry php_dom_notation_class_functions[] = {
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ publicId string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-54F2B4D0
+Since:
+*/
+int dom_notation_public_id_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlEntityPtr nodep;
+
+ nodep = (xmlEntityPtr) dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (nodep->ExternalID) {
+ ZVAL_STRING(*retval, (char *) (nodep->ExternalID), 1);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ systemId string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-E8AAB1D0
+Since:
+*/
+int dom_notation_system_id_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlEntityPtr nodep;
+
+ nodep = (xmlEntityPtr) dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (nodep->SystemID) {
+ ZVAL_STRING(*retval, (char *) (nodep->SystemID), 1);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
new file mode 100644
index 0000000..c3b0ee0
--- /dev/null
+++ b/ext/dom/php_dom.c
@@ -0,0 +1,1682 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ | Marcus Borger <helly@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "ext/standard/php_rand.h"
+#include "php_dom.h"
+#include "dom_properties.h"
+#include "zend_interfaces.h"
+
+#include "ext/standard/info.h"
+#define PHP_XPATH 1
+#define PHP_XPTR 2
+
+/* {{{ class entries */
+zend_class_entry *dom_node_class_entry;
+zend_class_entry *dom_domexception_class_entry;
+zend_class_entry *dom_domstringlist_class_entry;
+zend_class_entry *dom_namelist_class_entry;
+zend_class_entry *dom_domimplementationlist_class_entry;
+zend_class_entry *dom_domimplementationsource_class_entry;
+zend_class_entry *dom_domimplementation_class_entry;
+zend_class_entry *dom_documentfragment_class_entry;
+zend_class_entry *dom_document_class_entry;
+zend_class_entry *dom_nodelist_class_entry;
+zend_class_entry *dom_namednodemap_class_entry;
+zend_class_entry *dom_characterdata_class_entry;
+zend_class_entry *dom_attr_class_entry;
+zend_class_entry *dom_element_class_entry;
+zend_class_entry *dom_text_class_entry;
+zend_class_entry *dom_comment_class_entry;
+zend_class_entry *dom_typeinfo_class_entry;
+zend_class_entry *dom_userdatahandler_class_entry;
+zend_class_entry *dom_domerror_class_entry;
+zend_class_entry *dom_domerrorhandler_class_entry;
+zend_class_entry *dom_domlocator_class_entry;
+zend_class_entry *dom_domconfiguration_class_entry;
+zend_class_entry *dom_cdatasection_class_entry;
+zend_class_entry *dom_documenttype_class_entry;
+zend_class_entry *dom_notation_class_entry;
+zend_class_entry *dom_entity_class_entry;
+zend_class_entry *dom_entityreference_class_entry;
+zend_class_entry *dom_processinginstruction_class_entry;
+zend_class_entry *dom_string_extend_class_entry;
+#if defined(LIBXML_XPATH_ENABLED)
+zend_class_entry *dom_xpath_class_entry;
+#endif
+zend_class_entry *dom_namespace_node_class_entry;
+/* }}} */
+
+zend_object_handlers dom_object_handlers;
+
+static HashTable classes;
+/* {{{ prop handler tables */
+static HashTable dom_domstringlist_prop_handlers;
+static HashTable dom_namelist_prop_handlers;
+static HashTable dom_domimplementationlist_prop_handlers;
+static HashTable dom_document_prop_handlers;
+static HashTable dom_node_prop_handlers;
+static HashTable dom_nodelist_prop_handlers;
+static HashTable dom_namednodemap_prop_handlers;
+static HashTable dom_characterdata_prop_handlers;
+static HashTable dom_attr_prop_handlers;
+static HashTable dom_element_prop_handlers;
+static HashTable dom_text_prop_handlers;
+static HashTable dom_typeinfo_prop_handlers;
+static HashTable dom_domerror_prop_handlers;
+static HashTable dom_domlocator_prop_handlers;
+static HashTable dom_documenttype_prop_handlers;
+static HashTable dom_notation_prop_handlers;
+static HashTable dom_entity_prop_handlers;
+static HashTable dom_processinginstruction_prop_handlers;
+static HashTable dom_namespace_node_prop_handlers;
+#if defined(LIBXML_XPATH_ENABLED)
+static HashTable dom_xpath_prop_handlers;
+#endif
+/* }}} */
+
+typedef int (*dom_read_t)(dom_object *obj, zval **retval TSRMLS_DC);
+typedef int (*dom_write_t)(dom_object *obj, zval *newval TSRMLS_DC);
+
+typedef struct _dom_prop_handler {
+ dom_read_t read_func;
+ dom_write_t write_func;
+} dom_prop_handler;
+
+/* {{{ int dom_node_is_read_only(xmlNodePtr node) */
+int dom_node_is_read_only(xmlNodePtr node) {
+ switch (node->type) {
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_NOTATION_NODE:
+ case XML_DTD_NODE:
+ case XML_ELEMENT_DECL:
+ case XML_ATTRIBUTE_DECL:
+ case XML_ENTITY_DECL:
+ case XML_NAMESPACE_DECL:
+ return SUCCESS;
+ break;
+ default:
+ if (node->doc == NULL) {
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+ }
+}
+/* }}} end dom_node_is_read_only */
+
+/* {{{ int dom_node_children_valid(xmlNodePtr node) */
+int dom_node_children_valid(xmlNodePtr node) {
+ switch (node->type) {
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_DTD_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_NOTATION_NODE:
+ return FAILURE;
+ break;
+ default:
+ return SUCCESS;
+ }
+}
+/* }}} end dom_node_children_valid */
+
+/* {{{ dom_get_doc_props() */
+dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
+{
+ dom_doc_propsptr doc_props;
+
+ if (document && document->doc_props) {
+ return document->doc_props;
+ } else {
+ doc_props = emalloc(sizeof(libxml_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;
+ doc_props->recover = 0;
+ doc_props->classmap = NULL;
+ if (document) {
+ document->doc_props = doc_props;
+ }
+ return doc_props;
+ }
+}
+
+static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc)
+{
+ dom_doc_propsptr source, dest;
+
+ if (source_doc && dest_doc) {
+
+ source = dom_get_doc_props(source_doc);
+ dest = dom_get_doc_props(dest_doc);
+
+ dest->formatoutput = source->formatoutput;
+ dest->validateonparse = source->validateonparse;
+ dest->resolveexternals = source->resolveexternals;
+ dest->preservewhitespace = source->preservewhitespace;
+ dest->substituteentities = source->substituteentities;
+ dest->stricterror = source->stricterror;
+ dest->recover = source->recover;
+ if (source->classmap) {
+ ALLOC_HASHTABLE(dest->classmap);
+ zend_hash_init(dest->classmap, 0, NULL, NULL, 0);
+ zend_hash_copy(dest->classmap, source->classmap, NULL, NULL, sizeof(zend_class_entry *));
+ }
+
+ }
+}
+
+int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC)
+{
+ dom_doc_propsptr doc_props;
+
+ if (document) {
+ doc_props = dom_get_doc_props(document);
+ if (doc_props->classmap == NULL) {
+ if (ce == NULL) {
+ return SUCCESS;
+ }
+ ALLOC_HASHTABLE(doc_props->classmap);
+ zend_hash_init(doc_props->classmap, 0, NULL, NULL, 0);
+ }
+ if (ce) {
+ return zend_hash_update(doc_props->classmap, basece->name, basece->name_length + 1, &ce, sizeof(zend_class_entry *), NULL);
+ } else {
+ zend_hash_del(doc_props->classmap, basece->name, basece->name_length + 1);
+ }
+ }
+ return SUCCESS;
+}
+
+zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece TSRMLS_DC)
+{
+ dom_doc_propsptr doc_props;
+ zend_class_entry **ce = NULL;
+
+ if (document) {
+ doc_props = dom_get_doc_props(document);
+ if (doc_props->classmap) {
+ if (zend_hash_find(doc_props->classmap, basece->name, basece->name_length + 1, (void**) &ce) == SUCCESS) {
+ return *ce;
+ }
+ }
+ }
+
+ return basece;
+}
+/* }}} */
+
+/* {{{ dom_get_strict_error() */
+int dom_get_strict_error(php_libxml_ref_obj *document) {
+ int stricterror;
+ dom_doc_propsptr doc_props;
+
+ doc_props = dom_get_doc_props(document);
+ stricterror = doc_props->stricterror;
+ if (document == NULL) {
+ efree(doc_props);
+ }
+
+ return stricterror;
+}
+/* }}} */
+
+/* {{{ xmlNodePtr dom_object_get_node(dom_object *obj) */
+PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj)
+{
+ if (obj && obj->ptr != NULL) {
+ return ((php_libxml_node_ptr *)obj->ptr)->node;
+ } else {
+ return NULL;
+ }
+}
+/* }}} end dom_object_get_node */
+
+/* {{{ dom_object *php_dom_object_get_data(xmlNodePtr obj) */
+PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj)
+{
+ if (obj && obj->_private != NULL) {
+ return (dom_object *) ((php_libxml_node_ptr *) obj->_private)->_private;
+ } else {
+ return NULL;
+ }
+}
+/* }}} end php_dom_object_get_data */
+
+/* {{{ dom_read_na */
+static int dom_read_na(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ *retval = NULL;
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot read property");
+ return FAILURE;
+}
+/* }}} */
+
+/* {{{ dom_write_na */
+static int dom_write_na(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot write property");
+ return FAILURE;
+}
+/* }}} */
+
+/* {{{ dom_register_prop_handler */
+static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_read_t read_func, dom_write_t write_func TSRMLS_DC)
+{
+ dom_prop_handler hnd;
+
+ hnd.read_func = read_func ? read_func : dom_read_na;
+ hnd.write_func = write_func ? write_func : dom_write_na;
+ zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(dom_prop_handler), NULL);
+}
+/* }}} */
+
+static zval **dom_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+{
+ dom_object *obj;
+ zval tmp_member;
+ zval **retval = NULL;
+ dom_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret = FAILURE;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ }
+
+ obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ if (ret == FAILURE) {
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+ return retval;
+}
+/* }}} */
+
+/* {{{ dom_read_property */
+zval *dom_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
+{
+ dom_object *obj;
+ zval tmp_member;
+ zval *retval;
+ dom_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ }
+
+ ret = FAILURE;
+ obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ } else if (instanceof_function(obj->std.ce, dom_node_class_entry TSRMLS_CC)) {
+ php_error(E_WARNING, "Couldn't fetch %s. Node no longer exists", obj->std.ce->name);
+ }
+ if (ret == SUCCESS) {
+ ret = hnd->read_func(obj, &retval TSRMLS_CC);
+ if (ret == SUCCESS) {
+ /* ensure we're creating a temporary variable */
+ Z_SET_REFCOUNT_P(retval, 0);
+ Z_UNSET_ISREF_P(retval);
+ } else {
+ retval = EG(uninitialized_zval_ptr);
+ }
+ } else {
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->read_property(object, member, type, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+ return retval;
+}
+/* }}} */
+
+/* {{{ dom_write_property */
+void dom_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC)
+{
+ dom_object *obj;
+ zval tmp_member;
+ dom_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ }
+
+ ret = FAILURE;
+ obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ if (ret == SUCCESS) {
+ hnd->write_func(obj, value TSRMLS_CC);
+ } else {
+ std_hnd = zend_get_std_object_handlers();
+ std_hnd->write_property(object, member, value, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+}
+/* }}} */
+
+/* {{{ dom_property_exists */
+static int dom_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC)
+{
+ dom_object *obj;
+ zval tmp_member;
+ dom_prop_handler *hnd;
+ zend_object_handlers *std_hnd;
+ int ret, retval=0;
+
+ if (member->type != IS_STRING) {
+ tmp_member = *member;
+ zval_copy_ctor(&tmp_member);
+ convert_to_string(&tmp_member);
+ member = &tmp_member;
+ }
+
+ ret = FAILURE;
+ obj = (dom_object *)zend_objects_get_address(object TSRMLS_CC);
+
+ if (obj->prop_handler != NULL) {
+ ret = zend_hash_find((HashTable *)obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
+ }
+ if (ret == SUCCESS) {
+ zval *tmp;
+
+ if (check_empty == 2) {
+ retval = 1;
+ } else if (hnd->read_func(obj, &tmp TSRMLS_CC) == SUCCESS) {
+ Z_SET_REFCOUNT_P(tmp, 1);
+ Z_UNSET_ISREF_P(tmp);
+ if (check_empty == 1) {
+ retval = zend_is_true(tmp);
+ } else if (check_empty == 0) {
+ retval = (Z_TYPE_P(tmp) != IS_NULL);
+ }
+ zval_ptr_dtor(&tmp);
+ }
+ } else {
+ std_hnd = zend_get_std_object_handlers();
+ retval = std_hnd->has_property(object, member, check_empty, key TSRMLS_CC);
+ }
+
+ if (member == &tmp_member) {
+ zval_dtor(member);
+ }
+ return retval;
+}
+/* }}} */
+
+static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
+{
+ dom_object *obj = zend_object_store_get_object(object TSRMLS_CC);
+ HashTable *debug_info,
+ *prop_handlers = obj->prop_handler,
+ *std_props;
+ HashPosition pos;
+ dom_prop_handler *entry;
+ zval *object_value,
+ *null_value;
+
+ *is_temp = 1;
+
+ ALLOC_HASHTABLE(debug_info);
+ ZEND_INIT_SYMTABLE_EX(debug_info, 32, 0);
+
+ std_props = zend_std_get_properties(object TSRMLS_CC);
+ zend_hash_copy(debug_info, std_props, (copy_ctor_func_t)zval_add_ref,
+ NULL, sizeof(zval*));
+
+ if (!prop_handlers) {
+ return debug_info;
+ }
+
+ ALLOC_INIT_ZVAL(object_value);
+ ZVAL_STRING(object_value, "(object value omitted)", 1);
+
+ ALLOC_INIT_ZVAL(null_value);
+ ZVAL_NULL(null_value);
+
+ for (zend_hash_internal_pointer_reset_ex(prop_handlers, &pos);
+ zend_hash_get_current_data_ex(prop_handlers, (void **)&entry, &pos)
+ == SUCCESS;
+ zend_hash_move_forward_ex(prop_handlers, &pos)) {
+ zval *value;
+ char *string_key = NULL;
+ uint string_length = 0;
+ ulong num_key;
+
+ if (entry->read_func(obj, &value TSRMLS_CC) == FAILURE) {
+ continue;
+ }
+
+ if (zend_hash_get_current_key_ex(prop_handlers, &string_key,
+ &string_length, &num_key, 0, &pos) != HASH_KEY_IS_STRING) {
+ continue;
+ }
+
+ if (value == EG(uninitialized_zval_ptr)) {
+ value = null_value;
+ } else if (Z_TYPE_P(value) == IS_OBJECT) {
+ /* these are zvalues create on demand, with refcount and is_ref
+ * status left in an uninitalized stated */
+ zval_dtor(value);
+ efree(value);
+
+ value = object_value;
+ } else {
+ /* see comment above */
+ Z_SET_REFCOUNT_P(value, 0);
+ Z_UNSET_ISREF_P(value);
+ }
+
+ zval_add_ref(&value);
+ zend_hash_add(debug_info, string_key, string_length,
+ &value, sizeof(zval *), NULL);
+ }
+
+ zval_ptr_dtor(&null_value);
+ zval_ptr_dtor(&object_value);
+
+ return debug_info;
+}
+/* }}} */
+
+static HashTable* dom_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
+{
+ return dom_get_debug_info_helper(object, is_temp TSRMLS_CC);
+}
+/* }}} */
+
+void *php_dom_export_node(zval *object TSRMLS_DC) /* {{{ */
+{
+ php_libxml_node_object *intern;
+ xmlNodePtr nodep = NULL;
+
+ intern = (php_libxml_node_object *)zend_object_store_get_object(object TSRMLS_CC);
+ if (intern && intern->node) {
+ nodep = intern->node->node;
+ }
+
+ return nodep;
+}
+/* }}} */
+
+/* {{{ proto somNode dom_import_simplexml(sxeobject node)
+ Get a simplexml_element object from dom to allow for processing */
+PHP_FUNCTION(dom_import_simplexml)
+{
+ zval *node;
+ xmlNodePtr nodep = NULL;
+ php_libxml_node_object *nodeobj;
+ int ret;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &node) == FAILURE) {
+ return;
+ }
+
+ nodeobj = (php_libxml_node_object *)zend_object_store_get_object(node TSRMLS_CC);
+ nodep = php_libxml_import_node(node TSRMLS_CC);
+
+ if (nodep && nodeobj && (nodep->type == XML_ELEMENT_NODE || nodep->type == XML_ATTRIBUTE_NODE)) {
+ DOM_RET_OBJ((xmlNodePtr) nodep, &ret, (dom_object *)nodeobj);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid Nodetype to import");
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+zend_object_value dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */
+{
+ zend_object_value retval;
+ void *new_object;
+ dom_object *intern;
+ dom_object *old_object;
+ struct _store_object *obj;
+ zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
+
+ obj = &EG(objects_store).object_buckets[handle].bucket.obj;
+
+ if (obj->clone == NULL) {
+ php_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(zobject)->name);
+ }
+
+ obj->clone(obj->object, &new_object TSRMLS_CC);
+
+ retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC);
+ intern = (dom_object *) new_object;
+ intern->handle = retval.handle;
+ retval.handlers = Z_OBJ_HT_P(zobject);
+
+ old_object = (dom_object *) obj->object;
+ zend_objects_clone_members(&intern->std, retval, &old_object->std, intern->handle TSRMLS_CC);
+
+ return retval;
+}
+/* }}} */
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_import_simplexml, 0, 0, 1)
+ ZEND_ARG_INFO(0, node)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+static const zend_function_entry dom_functions[] = {
+ PHP_FE(dom_import_simplexml, arginfo_dom_import_simplexml)
+ PHP_FE_END
+};
+
+static zend_object_handlers* dom_get_obj_handlers(TSRMLS_D) {
+ return &dom_object_handlers;
+}
+
+static const zend_module_dep dom_deps[] = {
+ ZEND_MOD_REQUIRED("libxml")
+ ZEND_MOD_CONFLICTS("domxml")
+ ZEND_MOD_END
+};
+
+zend_module_entry dom_module_entry = { /* {{{ */
+ STANDARD_MODULE_HEADER_EX, NULL,
+ dom_deps,
+ "dom",
+ dom_functions,
+ PHP_MINIT(dom),
+ PHP_MSHUTDOWN(dom),
+ NULL,
+ NULL,
+ PHP_MINFO(dom),
+ DOM_API_VERSION, /* Extension versionnumber */
+ STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+#ifdef COMPILE_DL_DOM
+ZEND_GET_MODULE(dom)
+#endif
+
+/* {{{ PHP_MINIT_FUNCTION(dom) */
+PHP_MINIT_FUNCTION(dom)
+{
+ zend_class_entry ce;
+
+ memcpy(&dom_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ dom_object_handlers.read_property = dom_read_property;
+ dom_object_handlers.write_property = dom_write_property;
+ dom_object_handlers.get_property_ptr_ptr = dom_get_property_ptr_ptr;
+ dom_object_handlers.clone_obj = dom_objects_store_clone_obj;
+ dom_object_handlers.has_property = dom_property_exists;
+ dom_object_handlers.get_debug_info = dom_get_debug_info;
+
+ zend_hash_init(&classes, 0, NULL, NULL, 1);
+
+ INIT_CLASS_ENTRY(ce, "DOMException", php_dom_domexception_class_functions);
+ dom_domexception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
+ dom_domexception_class_entry->ce_flags |= ZEND_ACC_FINAL;
+ zend_declare_property_long(dom_domexception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
+
+ REGISTER_DOM_CLASS(ce, "DOMStringList", NULL, php_dom_domstringlist_class_functions, dom_domstringlist_class_entry);
+
+ zend_hash_init(&dom_domstringlist_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_domstringlist_prop_handlers, "length", dom_domstringlist_length_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domstringlist_prop_handlers, sizeof(dom_domstringlist_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMNameList", NULL, php_dom_namelist_class_functions, dom_namelist_class_entry);
+
+ zend_hash_init(&dom_namelist_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_namelist_prop_handlers, "length", dom_namelist_length_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namelist_prop_handlers, sizeof(dom_namelist_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMImplementationList", NULL, php_dom_domimplementationlist_class_functions, dom_domimplementationlist_class_entry);
+
+ zend_hash_init(&dom_domimplementationlist_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_domimplementationlist_prop_handlers, "length", dom_domimplementationlist_length_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domimplementationlist_prop_handlers, sizeof(dom_domimplementationlist_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMImplementationSource", NULL, php_dom_domimplementationsource_class_functions, dom_domimplementationsource_class_entry);
+ REGISTER_DOM_CLASS(ce, "DOMImplementation", NULL, php_dom_domimplementation_class_functions, dom_domimplementation_class_entry);
+
+ REGISTER_DOM_CLASS(ce, "DOMNode", NULL, php_dom_node_class_functions, dom_node_class_entry);
+
+ zend_hash_init(&dom_node_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "childNodes", dom_node_child_nodes_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "firstChild", dom_node_first_child_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "lastChild", dom_node_last_child_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "previousSibling", dom_node_previous_sibling_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "nextSibling", dom_node_next_sibling_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "attributes", dom_node_attributes_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "prefix", dom_node_prefix_read, dom_node_prefix_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "localName", dom_node_local_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "baseURI", dom_node_base_uri_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_node_prop_handlers, "textContent", dom_node_text_content_read, dom_node_text_content_write TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMNameSpaceNode", NULL, NULL, dom_namespace_node_class_entry);
+
+ zend_hash_init(&dom_namespace_node_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeValue", dom_node_node_value_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "nodeType", dom_node_node_type_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "prefix", dom_node_prefix_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "localName", dom_node_local_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "namespaceURI", dom_node_namespace_uri_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "ownerDocument", dom_node_owner_document_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_namespace_node_prop_handlers, "parentNode", dom_node_parent_node_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namespace_node_prop_handlers, sizeof(dom_namespace_node_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMDocumentFragment", dom_node_class_entry, php_dom_documentfragment_class_functions, dom_documentfragment_class_entry);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMDocument", dom_node_class_entry, php_dom_document_class_functions, dom_document_class_entry);
+ zend_hash_init(&dom_document_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_document_prop_handlers, "doctype", dom_document_doctype_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "implementation", dom_document_implementation_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "documentElement", dom_document_document_element_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "actualEncoding", dom_document_encoding_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "encoding", dom_document_encoding_read, dom_document_encoding_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "xmlEncoding", dom_document_encoding_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "standalone", dom_document_standalone_read, dom_document_standalone_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "xmlStandalone", dom_document_standalone_read, dom_document_standalone_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "version", dom_document_version_read, dom_document_version_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_document_prop_handlers, "xmlVersion", dom_document_version_read, dom_document_version_write TSRMLS_CC);
+ 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, "recover", dom_document_recover_read, dom_document_recover_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);
+
+ INIT_CLASS_ENTRY(ce, "DOMNodeList", php_dom_nodelist_class_functions);
+ ce.create_object = dom_nnodemap_objects_new;
+ dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ dom_nodelist_class_entry->get_iterator = php_dom_get_iterator;
+ zend_class_implements(dom_nodelist_class_entry TSRMLS_CC, 1, zend_ce_traversable);
+
+ zend_hash_init(&dom_nodelist_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_nodelist_prop_handlers, "length", dom_nodelist_length_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_nodelist_prop_handlers, sizeof(dom_nodelist_prop_handlers), NULL);
+
+ INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", php_dom_namednodemap_class_functions);
+ ce.create_object = dom_nnodemap_objects_new;
+ dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+ dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
+ zend_class_implements(dom_namednodemap_class_entry TSRMLS_CC, 1, zend_ce_traversable);
+
+ zend_hash_init(&dom_namednodemap_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_namednodemap_prop_handlers, "length", dom_namednodemap_length_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namednodemap_prop_handlers, sizeof(dom_namednodemap_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMCharacterData", dom_node_class_entry, php_dom_characterdata_class_functions, dom_characterdata_class_entry);
+
+ zend_hash_init(&dom_characterdata_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_characterdata_prop_handlers, "length", dom_characterdata_length_read, NULL TSRMLS_CC);
+ zend_hash_merge(&dom_characterdata_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_characterdata_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMAttr", dom_node_class_entry, php_dom_attr_class_functions, dom_attr_class_entry);
+
+ zend_hash_init(&dom_attr_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_attr_prop_handlers, "name", dom_attr_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_attr_prop_handlers, "specified", dom_attr_specified_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_attr_prop_handlers, "value", dom_attr_value_read, dom_attr_value_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_attr_prop_handlers, "ownerElement", dom_attr_owner_element_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_attr_prop_handlers, "schemaTypeInfo", dom_attr_schema_type_info_read, NULL TSRMLS_CC);
+ zend_hash_merge(&dom_attr_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_attr_prop_handlers, sizeof(dom_attr_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMElement", dom_node_class_entry, php_dom_element_class_functions, dom_element_class_entry);
+
+ zend_hash_init(&dom_element_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_element_prop_handlers, "schemaTypeInfo", dom_element_schema_type_info_read, NULL TSRMLS_CC);
+ zend_hash_merge(&dom_element_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_element_prop_handlers, sizeof(dom_element_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMText", dom_characterdata_class_entry, php_dom_text_class_functions, dom_text_class_entry);
+
+ zend_hash_init(&dom_text_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL TSRMLS_CC);
+ zend_hash_merge(&dom_text_prop_handlers, &dom_characterdata_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_text_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMComment", dom_characterdata_class_entry, php_dom_comment_class_functions, dom_comment_class_entry);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMTypeinfo", NULL, php_dom_typeinfo_class_functions, dom_typeinfo_class_entry);
+
+ zend_hash_init(&dom_typeinfo_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeName", dom_typeinfo_type_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeNamespace", dom_typeinfo_type_namespace_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_typeinfo_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMUserDataHandler", NULL, php_dom_userdatahandler_class_functions, dom_userdatahandler_class_entry);
+ REGISTER_DOM_CLASS(ce, "DOMDomError", NULL, php_dom_domerror_class_functions, dom_domerror_class_entry);
+
+ zend_hash_init(&dom_domerror_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_domerror_prop_handlers, "severity", dom_domerror_severity_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domerror_prop_handlers, "message", dom_domerror_message_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domerror_prop_handlers, "type", dom_domerror_type_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domerror_prop_handlers, "relatedException", dom_domerror_related_exception_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domerror_prop_handlers, "related_data", dom_domerror_related_data_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domerror_prop_handlers, "location", dom_domerror_location_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domerror_prop_handlers, sizeof(dom_domerror_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMErrorHandler", NULL, php_dom_domerrorhandler_class_functions, dom_domerrorhandler_class_entry);
+ REGISTER_DOM_CLASS(ce, "DOMLocator", NULL, php_dom_domlocator_class_functions, dom_domlocator_class_entry);
+
+ zend_hash_init(&dom_domlocator_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_domlocator_prop_handlers, "lineNumber", dom_domlocator_line_number_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domlocator_prop_handlers, "columnNumber", dom_domlocator_column_number_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domlocator_prop_handlers, "offset", dom_domlocator_offset_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domlocator_prop_handlers, "relatedNode", dom_domlocator_related_node_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_domlocator_prop_handlers, "uri", dom_domlocator_uri_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domlocator_prop_handlers, sizeof(dom_domlocator_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMConfiguration", NULL, php_dom_domconfiguration_class_functions, dom_domconfiguration_class_entry);
+ REGISTER_DOM_CLASS(ce, "DOMCdataSection", dom_text_class_entry, php_dom_cdatasection_class_functions, dom_cdatasection_class_entry);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMDocumentType", dom_node_class_entry, php_dom_documenttype_class_functions, dom_documenttype_class_entry);
+
+ zend_hash_init(&dom_documenttype_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_documenttype_prop_handlers, "entities", dom_documenttype_entities_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_documenttype_prop_handlers, "notations", dom_documenttype_notations_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_documenttype_prop_handlers, "publicId", dom_documenttype_public_id_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_documenttype_prop_handlers, "systemId", dom_documenttype_system_id_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_documenttype_prop_handlers, "internalSubset", dom_documenttype_internal_subset_read, NULL TSRMLS_CC);
+ zend_hash_merge(&dom_documenttype_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_documenttype_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMNotation", dom_node_class_entry, php_dom_notation_class_functions, dom_notation_class_entry);
+
+ zend_hash_init(&dom_notation_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL TSRMLS_CC);
+ zend_hash_merge(&dom_notation_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_notation_prop_handlers, sizeof(dom_notation_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMEntity", dom_node_class_entry, php_dom_entity_class_functions, dom_entity_class_entry);
+
+ zend_hash_init(&dom_entity_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_entity_prop_handlers, "systemId", dom_entity_system_id_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_entity_prop_handlers, "notationName", dom_entity_notation_name_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_entity_prop_handlers, "actualEncoding", dom_entity_actual_encoding_read, dom_entity_actual_encoding_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_entity_prop_handlers, "encoding", dom_entity_encoding_read, dom_entity_encoding_write TSRMLS_CC);
+ dom_register_prop_handler(&dom_entity_prop_handlers, "version", dom_entity_version_read, dom_entity_version_write TSRMLS_CC);
+ zend_hash_merge(&dom_entity_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_entity_prop_handlers, sizeof(dom_entity_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMEntityReference", dom_node_class_entry, php_dom_entityreference_class_functions, dom_entityreference_class_entry);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_entity_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMProcessingInstruction", dom_node_class_entry, php_dom_processinginstruction_class_functions, dom_processinginstruction_class_entry);
+
+ zend_hash_init(&dom_processinginstruction_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL TSRMLS_CC);
+ dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "data", dom_processinginstruction_data_read, dom_processinginstruction_data_write TSRMLS_CC);
+ zend_hash_merge(&dom_processinginstruction_prop_handlers, &dom_node_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_processinginstruction_prop_handlers, sizeof(dom_processinginstruction_prop_handlers), NULL);
+
+ REGISTER_DOM_CLASS(ce, "DOMStringExtend", NULL, php_dom_string_extend_class_functions, dom_string_extend_class_entry);
+
+#if defined(LIBXML_XPATH_ENABLED)
+ INIT_CLASS_ENTRY(ce, "DOMXPath", php_dom_xpath_class_functions);
+ ce.create_object = dom_xpath_objects_new;
+ dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
+
+ zend_hash_init(&dom_xpath_prop_handlers, 0, NULL, NULL, 1);
+ dom_register_prop_handler(&dom_xpath_prop_handlers, "document", dom_xpath_document_read, NULL TSRMLS_CC);
+ zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_xpath_prop_handlers, sizeof(dom_xpath_prop_handlers), NULL);
+#endif
+
+ REGISTER_LONG_CONSTANT("XML_ELEMENT_NODE", XML_ELEMENT_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NODE", XML_ATTRIBUTE_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_TEXT_NODE", XML_TEXT_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_CDATA_SECTION_NODE", XML_CDATA_SECTION_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ENTITY_REF_NODE", XML_ENTITY_REF_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ENTITY_NODE", XML_ENTITY_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_PI_NODE", XML_PI_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_COMMENT_NODE", XML_COMMENT_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_DOCUMENT_NODE", XML_DOCUMENT_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_DOCUMENT_TYPE_NODE", XML_DOCUMENT_TYPE_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_DOCUMENT_FRAG_NODE", XML_DOCUMENT_FRAG_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_NOTATION_NODE", XML_NOTATION_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_HTML_DOCUMENT_NODE", XML_HTML_DOCUMENT_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_DTD_NODE", XML_DTD_NODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ELEMENT_DECL_NODE", XML_ELEMENT_DECL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_DECL_NODE", XML_ATTRIBUTE_DECL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ENTITY_DECL_NODE", XML_ENTITY_DECL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_NAMESPACE_DECL_NODE", XML_NAMESPACE_DECL, CONST_CS | CONST_PERSISTENT);
+#ifdef XML_GLOBAL_NAMESPACE
+ REGISTER_LONG_CONSTANT("XML_GLOBAL_NAMESPACE", XML_GLOBAL_NAMESPACE, CONST_CS | CONST_PERSISTENT);
+#endif
+ REGISTER_LONG_CONSTANT("XML_LOCAL_NAMESPACE", XML_LOCAL_NAMESPACE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_CDATA", XML_ATTRIBUTE_CDATA, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ID", XML_ATTRIBUTE_ID, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_IDREF", XML_ATTRIBUTE_IDREF, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_IDREFS", XML_ATTRIBUTE_IDREFS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ENTITY", XML_ATTRIBUTE_ENTITIES, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NMTOKEN", XML_ATTRIBUTE_NMTOKEN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NMTOKENS", XML_ATTRIBUTE_NMTOKENS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_ENUMERATION", XML_ATTRIBUTE_ENUMERATION, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("XML_ATTRIBUTE_NOTATION", XML_ATTRIBUTE_NOTATION, CONST_CS | CONST_PERSISTENT);
+
+ /* DOMException Codes */
+ REGISTER_LONG_CONSTANT("DOM_PHP_ERR", PHP_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_INDEX_SIZE_ERR", INDEX_SIZE_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOMSTRING_SIZE_ERR", DOMSTRING_SIZE_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_HIERARCHY_REQUEST_ERR", HIERARCHY_REQUEST_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_WRONG_DOCUMENT_ERR", WRONG_DOCUMENT_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_INVALID_CHARACTER_ERR", INVALID_CHARACTER_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_NO_DATA_ALLOWED_ERR", NO_DATA_ALLOWED_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_NO_MODIFICATION_ALLOWED_ERR", NO_MODIFICATION_ALLOWED_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_NOT_FOUND_ERR", NOT_FOUND_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_NOT_SUPPORTED_ERR", NOT_SUPPORTED_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_INUSE_ATTRIBUTE_ERR", INUSE_ATTRIBUTE_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_INVALID_STATE_ERR", INVALID_STATE_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_SYNTAX_ERR", SYNTAX_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_INVALID_MODIFICATION_ERR", INVALID_MODIFICATION_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_NAMESPACE_ERR", NAMESPACE_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_INVALID_ACCESS_ERR", INVALID_ACCESS_ERR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("DOM_VALIDATION_ERR", VALIDATION_ERR, CONST_CS | CONST_PERSISTENT);
+
+ php_libxml_register_export(dom_node_class_entry, php_dom_export_node);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ */
+PHP_MINFO_FUNCTION(dom)
+{
+ php_info_print_table_start();
+ php_info_print_table_row(2, "DOM/XML", "enabled");
+ php_info_print_table_row(2, "DOM/XML API Version", DOM_API_VERSION);
+ 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
+#ifdef LIBXML_SCHEMAS_ENABLED
+ php_info_print_table_row(2, "Schema Support", "enabled");
+ php_info_print_table_row(2, "RelaxNG Support", "enabled");
+#endif
+ php_info_print_table_end();
+}
+/* }}} */
+
+PHP_MSHUTDOWN_FUNCTION(dom) /* {{{ */
+{
+ zend_hash_destroy(&dom_domstringlist_prop_handlers);
+ zend_hash_destroy(&dom_namelist_prop_handlers);
+ zend_hash_destroy(&dom_domimplementationlist_prop_handlers);
+ zend_hash_destroy(&dom_document_prop_handlers);
+ zend_hash_destroy(&dom_node_prop_handlers);
+ zend_hash_destroy(&dom_namespace_node_prop_handlers);
+ zend_hash_destroy(&dom_nodelist_prop_handlers);
+ zend_hash_destroy(&dom_namednodemap_prop_handlers);
+ zend_hash_destroy(&dom_characterdata_prop_handlers);
+ zend_hash_destroy(&dom_attr_prop_handlers);
+ zend_hash_destroy(&dom_element_prop_handlers);
+ zend_hash_destroy(&dom_text_prop_handlers);
+ zend_hash_destroy(&dom_typeinfo_prop_handlers);
+ zend_hash_destroy(&dom_domerror_prop_handlers);
+ zend_hash_destroy(&dom_domlocator_prop_handlers);
+ zend_hash_destroy(&dom_documenttype_prop_handlers);
+ zend_hash_destroy(&dom_notation_prop_handlers);
+ zend_hash_destroy(&dom_entity_prop_handlers);
+ zend_hash_destroy(&dom_processinginstruction_prop_handlers);
+#if defined(LIBXML_XPATH_ENABLED)
+ zend_hash_destroy(&dom_xpath_prop_handlers);
+#endif
+ zend_hash_destroy(&classes);
+
+/* If you want do find memleaks in this module, compile libxml2 with --with-mem-debug and
+ uncomment the following line, this will tell you the amount of not freed memory
+ and the total used memory into apaches error_log */
+/* xmlMemoryDump();*/
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ node_list_unlink */
+void node_list_unlink(xmlNodePtr node TSRMLS_DC)
+{
+ dom_object *wrapper;
+
+ while (node != NULL) {
+
+ wrapper = php_dom_object_get_data(node);
+
+ if (wrapper != NULL ) {
+ xmlUnlinkNode(node);
+ } else {
+ if (node->type == XML_ENTITY_REF_NODE)
+ break;
+ node_list_unlink(node->children TSRMLS_CC);
+
+ switch (node->type) {
+ case XML_ATTRIBUTE_DECL:
+ case XML_DTD_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ case XML_ENTITY_DECL:
+ case XML_ATTRIBUTE_NODE:
+ case XML_TEXT_NODE:
+ break;
+ default:
+ node_list_unlink((xmlNodePtr) node->properties TSRMLS_CC);
+ }
+
+ }
+
+ node = node->next;
+ }
+}
+/* }}} end node_list_unlink */
+
+#if defined(LIBXML_XPATH_ENABLED)
+/* {{{ dom_xpath_objects_free_storage */
+void dom_xpath_objects_free_storage(void *object TSRMLS_DC)
+{
+ dom_xpath_object *intern = (dom_xpath_object *)object;
+
+ zend_object_std_dtor(&intern->std TSRMLS_CC);
+
+ if (intern->ptr != NULL) {
+ xmlXPathFreeContext((xmlXPathContextPtr) intern->ptr);
+ php_libxml_decrement_doc_ref((php_libxml_node_object *) intern TSRMLS_CC);
+ intern->ptr = NULL;
+ }
+
+ if (intern->registered_phpfunctions) {
+ zend_hash_destroy(intern->registered_phpfunctions);
+ FREE_HASHTABLE(intern->registered_phpfunctions);
+ }
+
+ if (intern->node_list) {
+ zend_hash_destroy(intern->node_list);
+ FREE_HASHTABLE(intern->node_list);
+ }
+
+ efree(object);
+}
+/* }}} */
+#endif
+
+/* {{{ dom_objects_free_storage */
+void dom_objects_free_storage(void *object TSRMLS_DC)
+{
+ dom_object *intern = (dom_object *)object;
+ int retcount;
+
+ zend_object_std_dtor(&intern->std TSRMLS_CC);
+
+ if (intern->ptr != NULL && ((php_libxml_node_ptr *)intern->ptr)->node != NULL) {
+ if (((xmlNodePtr) ((php_libxml_node_ptr *)intern->ptr)->node)->type != XML_DOCUMENT_NODE && ((xmlNodePtr) ((php_libxml_node_ptr *)intern->ptr)->node)->type != XML_HTML_DOCUMENT_NODE) {
+ php_libxml_node_decrement_resource((php_libxml_node_object *) intern TSRMLS_CC);
+ } else {
+ php_libxml_decrement_node_ptr((php_libxml_node_object *) intern TSRMLS_CC);
+ retcount = php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ }
+ intern->ptr = NULL;
+ }
+
+ efree(object);
+}
+/* }}} */
+
+void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns TSRMLS_DC) /* {{{ */
+{
+ dom_nnodemap_object *mapptr;
+ zval *baseobj = NULL;
+
+ mapptr = (dom_nnodemap_object *)intern->ptr;
+ if (basenode) {
+ MAKE_STD_ZVAL(baseobj);
+ baseobj->type = IS_OBJECT;
+ Z_SET_ISREF_P(baseobj);
+ baseobj->value.obj.handle = basenode->handle;
+ baseobj->value.obj.handlers = dom_get_obj_handlers(TSRMLS_C);
+ zval_copy_ctor(baseobj);
+ }
+ mapptr->baseobjptr = baseobj;
+ mapptr->baseobj = basenode;
+ mapptr->nodetype = ntype;
+ mapptr->ht = ht;
+ mapptr->local = local;
+ mapptr->ns = ns;
+
+}
+/* }}} */
+
+static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC) /* {{{ */
+{
+ zend_class_entry *base_class;
+ dom_object *intern;
+
+ if (instanceof_function(class_type, dom_xpath_class_entry TSRMLS_CC)) {
+ intern = emalloc(sizeof(dom_xpath_object));
+ memset(intern, 0, sizeof(dom_xpath_object));
+ } else {
+ intern = emalloc(sizeof(dom_object));
+ }
+ intern->ptr = NULL;
+ intern->prop_handler = NULL;
+ intern->document = NULL;
+
+ base_class = class_type;
+ while(base_class->type != ZEND_INTERNAL_CLASS && base_class->parent != NULL) {
+ base_class = base_class->parent;
+ }
+
+ zend_hash_find(&classes, base_class->name, base_class->name_length + 1, (void **) &intern->prop_handler);
+
+ zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+ if (hash_copy) {
+ object_properties_init(&intern->std, class_type);
+ }
+
+ return intern;
+}
+/* }}} */
+
+/* {{{ dom_objects_clone */
+void dom_objects_clone(void *object, void **object_clone TSRMLS_DC)
+{
+ dom_object *intern = (dom_object *) object;
+ dom_object *clone;
+ xmlNodePtr node;
+ xmlNodePtr cloned_node;
+
+ clone = dom_objects_set_class(intern->std.ce, 0 TSRMLS_CC);
+
+ if (instanceof_function(intern->std.ce, dom_node_class_entry TSRMLS_CC)) {
+ node = (xmlNodePtr)dom_object_get_node((dom_object *) object);
+ if (node != NULL) {
+ cloned_node = xmlDocCopyNode(node, node->doc, 1);
+ if (cloned_node != NULL) {
+ /* If we cloned a document then we must create new doc proxy */
+ if (cloned_node->doc == node->doc) {
+ clone->document = intern->document;
+ }
+ php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc TSRMLS_CC);
+ php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, (void *)clone TSRMLS_CC);
+ if (intern->document != clone->document) {
+ dom_copy_doc_props(intern->document, clone->document);
+ }
+ }
+
+ }
+ }
+
+ *object_clone = (void *) clone;
+}
+/* }}} */
+
+/* {{{ dom_objects_new */
+zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC)
+{
+ zend_object_value retval;
+ dom_object *intern;
+
+ intern = dom_objects_set_class(class_type, 1 TSRMLS_CC);
+
+ retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)dom_objects_free_storage, dom_objects_clone TSRMLS_CC);
+ intern->handle = retval.handle;
+ retval.handlers = dom_get_obj_handlers(TSRMLS_C);
+
+ return retval;
+}
+/* }}} */
+
+#if defined(LIBXML_XPATH_ENABLED)
+/* {{{ zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC) */
+zend_object_value dom_xpath_objects_new(zend_class_entry *class_type TSRMLS_DC)
+{
+ zend_object_value retval;
+ dom_xpath_object *intern;
+
+ intern = (dom_xpath_object *)dom_objects_set_class(class_type, 1 TSRMLS_CC);
+ intern->registerPhpFunctions = 0;
+ intern->registered_phpfunctions = NULL;
+ intern->node_list = NULL;
+
+ ALLOC_HASHTABLE(intern->registered_phpfunctions);
+ zend_hash_init(intern->registered_phpfunctions, 0, NULL, ZVAL_PTR_DTOR, 0);
+
+ retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)dom_xpath_objects_free_storage, dom_objects_clone TSRMLS_CC);
+ intern->handle = retval.handle;
+ retval.handlers = dom_get_obj_handlers(TSRMLS_C);
+
+ return retval;
+}
+/* }}} */
+#endif
+
+static void dom_nnodemap_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */
+{
+ zval *baseobj;
+ dom_object *intern;
+ dom_nnodemap_object *objmap;
+
+ intern = (dom_object *)object;
+ objmap = (dom_nnodemap_object *)intern->ptr;
+
+ if (objmap) {
+ if (objmap->local) {
+ xmlFree(objmap->local);
+ }
+ if (objmap->ns) {
+ xmlFree(objmap->ns);
+ }
+ if (objmap->baseobjptr) {
+ baseobj = objmap->baseobjptr;
+ zval_ptr_dtor((zval **)&baseobj);
+ }
+ efree(objmap);
+ intern->ptr = NULL;
+ }
+
+
+}
+/* }}} */
+
+void dom_nnodemap_objects_free_storage(void *object TSRMLS_DC) /* {{{ */
+{
+ dom_object *intern = (dom_object *)object;
+
+ php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+
+ zend_object_std_dtor(&intern->std TSRMLS_CC);
+
+ efree(object);
+}
+/* }}} */
+
+zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+{
+ zend_object_value retval;
+ dom_object *intern;
+ dom_nnodemap_object *objmap;
+
+ intern = dom_objects_set_class(class_type, 1 TSRMLS_CC);
+ intern->ptr = emalloc(sizeof(dom_nnodemap_object));
+ objmap = (dom_nnodemap_object *)intern->ptr;
+ objmap->baseobj = NULL;
+ objmap->baseobjptr = NULL;
+ objmap->nodetype = 0;
+ objmap->ht = NULL;
+ objmap->local = NULL;
+ objmap->ns = NULL;
+
+ retval.handle = zend_objects_store_put(intern, dom_nnodemap_object_dtor, (zend_objects_free_object_storage_t)dom_nnodemap_objects_free_storage, dom_objects_clone TSRMLS_CC);
+ intern->handle = retval.handle;
+ retval.handlers = dom_get_obj_handlers(TSRMLS_C);
+
+ return retval;
+}
+/* }}} */
+
+void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC) /* {{{ */
+{
+ zend_class_entry *ce;
+
+ if (ce_type == DOM_NAMEDNODEMAP) {
+ ce = dom_namednodemap_class_entry;
+ } else {
+ ce = dom_nodelist_class_entry;
+ }
+
+ object_init_ex(return_value, ce);
+}
+/* }}} */
+
+/* {{{ php_dom_create_object */
+PHP_DOM_EXPORT zval *php_dom_create_object(xmlNodePtr obj, int *found, zval *return_value, dom_object *domobj TSRMLS_DC)
+{
+ zval *wrapper;
+ zend_class_entry *ce;
+ dom_object *intern;
+
+ *found = 0;
+
+ if (!obj) {
+ ALLOC_ZVAL(wrapper);
+ ZVAL_NULL(wrapper);
+ return wrapper;
+ }
+
+ if ((intern = (dom_object *) php_dom_object_get_data((void *) obj))) {
+ return_value->type = IS_OBJECT;
+ Z_SET_ISREF_P(return_value);
+ return_value->value.obj.handle = intern->handle;
+ return_value->value.obj.handlers = dom_get_obj_handlers(TSRMLS_C);
+ zval_copy_ctor(return_value);
+ *found = 1;
+ return return_value;
+ }
+
+ wrapper = return_value;
+
+ switch (obj->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+ {
+ ce = dom_document_class_entry;
+ break;
+ }
+ case XML_DTD_NODE:
+ case XML_DOCUMENT_TYPE_NODE:
+ {
+ ce = dom_documenttype_class_entry;
+ break;
+ }
+ case XML_ELEMENT_NODE:
+ {
+ ce = dom_element_class_entry;
+ break;
+ }
+ case XML_ATTRIBUTE_NODE:
+ {
+ ce = dom_attr_class_entry;
+ break;
+ }
+ case XML_TEXT_NODE:
+ {
+ ce = dom_text_class_entry;
+ break;
+ }
+ case XML_COMMENT_NODE:
+ {
+ ce = dom_comment_class_entry;
+ break;
+ }
+ case XML_PI_NODE:
+ {
+ ce = dom_processinginstruction_class_entry;
+ break;
+ }
+ case XML_ENTITY_REF_NODE:
+ {
+ ce = dom_entityreference_class_entry;
+ break;
+ }
+ case XML_ENTITY_DECL:
+ case XML_ELEMENT_DECL:
+ {
+ ce = dom_entity_class_entry;
+ break;
+ }
+ case XML_CDATA_SECTION_NODE:
+ {
+ ce = dom_cdatasection_class_entry;
+ break;
+ }
+ case XML_DOCUMENT_FRAG_NODE:
+ {
+ ce = dom_documentfragment_class_entry;
+ break;
+ }
+ case XML_NOTATION_NODE:
+ {
+ ce = dom_notation_class_entry;
+ break;
+ }
+ case XML_NAMESPACE_DECL:
+ {
+ ce = dom_namespace_node_class_entry;
+ break;
+ }
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported node type: %d", Z_TYPE_P(obj));
+ ZVAL_NULL(wrapper);
+ return wrapper;
+ }
+
+ if (domobj && domobj->document) {
+ ce = dom_get_doc_classmap(domobj->document, ce TSRMLS_CC);
+ }
+ object_init_ex(wrapper, ce);
+
+ intern = (dom_object *)zend_objects_get_address(wrapper TSRMLS_CC);
+ if (obj->doc != NULL) {
+ if (domobj != NULL) {
+ intern->document = domobj->document;
+ }
+ php_libxml_increment_doc_ref((php_libxml_node_object *)intern, obj->doc TSRMLS_CC);
+ }
+
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, obj, (void *)intern TSRMLS_CC);
+ return (wrapper);
+}
+/* }}} end php_domobject_new */
+
+void php_dom_create_implementation(zval **retval TSRMLS_DC) {
+ object_init_ex(*retval, dom_domimplementation_class_entry);
+}
+
+/* {{{ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) */
+int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child)
+{
+ xmlNodePtr nodep;
+
+ if (parent == NULL || child == NULL || child->doc != parent->doc) {
+ return SUCCESS;
+ }
+
+ nodep = parent;
+
+ while (nodep) {
+ if (nodep == child) {
+ return FAILURE;
+ }
+ nodep = nodep->parent;
+ }
+
+ return SUCCESS;
+}
+/* }}} end dom_hierarchy */
+
+/* {{{ dom_has_feature(char *feature, char *version) */
+int dom_has_feature(char *feature, char *version)
+{
+ int retval = 0;
+
+ if (!(strcmp (version, "1.0") && strcmp (version,"2.0") && strcmp(version, ""))) {
+ if ((!strcasecmp(feature, "Core") && !strcmp (version, "1.0")) || !strcasecmp(feature, "XML"))
+ retval = 1;
+ }
+
+ return retval;
+}
+/* }}} end dom_has_feature */
+
+xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index) /* {{{ */
+{
+ xmlNodePtr ret = NULL;
+
+ while (nodep != NULL && (*cur <= index || index == -1)) {
+ if (nodep->type == XML_ELEMENT_NODE) {
+ if (xmlStrEqual(nodep->name, (xmlChar *)local) || xmlStrEqual((xmlChar *)"*", (xmlChar *)local)) {
+ if (ns == NULL || (nodep->ns != NULL && (xmlStrEqual(nodep->ns->href, (xmlChar *)ns) || xmlStrEqual((xmlChar *)"*", (xmlChar *)ns)))) {
+ if (*cur == index) {
+ ret = nodep;
+ break;
+ }
+ (*cur)++;
+ }
+ }
+ ret = dom_get_elements_by_tag_name_ns_raw(nodep->children, ns, local, cur, index);
+ if (ret != NULL) {
+ break;
+ }
+ }
+ nodep = nodep->next;
+ }
+ return ret;
+}
+/* }}} */
+/* }}} end dom_element_get_elements_by_tag_name_ns_raw */
+
+/* {{{ void dom_normalize (xmlNodePtr nodep TSRMLS_DC) */
+void dom_normalize (xmlNodePtr nodep TSRMLS_DC)
+{
+ xmlNodePtr child, nextp, newnextp;
+ xmlAttrPtr attr;
+ xmlChar *strContent;
+
+ child = nodep->children;
+ while(child != NULL) {
+ switch (child->type) {
+ case XML_TEXT_NODE:
+ nextp = child->next;
+ while (nextp != NULL) {
+ if (nextp->type == XML_TEXT_NODE) {
+ newnextp = nextp->next;
+ strContent = xmlNodeGetContent(nextp);
+ xmlNodeAddContent(child, strContent);
+ xmlFree(strContent);
+ xmlUnlinkNode(nextp);
+ php_libxml_node_free_resource(nextp TSRMLS_CC);
+ nextp = newnextp;
+ } else {
+ break;
+ }
+ }
+ break;
+ case XML_ELEMENT_NODE:
+ dom_normalize (child TSRMLS_CC);
+ attr = child->properties;
+ while (attr != NULL) {
+ dom_normalize((xmlNodePtr) attr TSRMLS_CC);
+ attr = attr->next;
+ }
+ break;
+ case XML_ATTRIBUTE_NODE:
+ dom_normalize (child TSRMLS_CC);
+ break;
+ default:
+ break;
+ }
+ child = child->next;
+ }
+}
+/* }}} end dom_normalize */
+
+
+/* {{{ void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) */
+void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) {
+ xmlNs *cur;
+
+ if (doc == NULL)
+ return;
+
+ if (doc->oldNs == NULL) {
+ doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
+ if (doc->oldNs == NULL) {
+ return;
+ }
+ memset(doc->oldNs, 0, sizeof(xmlNs));
+ doc->oldNs->type = XML_LOCAL_NAMESPACE;
+ doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
+ doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
+ }
+
+ cur = doc->oldNs;
+ while (cur->next != NULL) {
+ cur = cur->next;
+ }
+ cur->next = ns;
+}
+/* }}} end dom_set_old_ns */
+
+/*
+http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
+
+NAMESPACE_ERR: Raised if
+
+1. the qualifiedName is a malformed qualified name
+2. the qualifiedName has a prefix and the namespaceURI is null
+*/
+
+/* {{{ int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) */
+int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len) {
+ if (name_len == 0) {
+ return NAMESPACE_ERR;
+ }
+
+ *localname = (char *)xmlSplitQName2((xmlChar *)qname, (xmlChar **) prefix);
+ if (*localname == NULL) {
+ *localname = (char *)xmlStrdup((xmlChar *)qname);
+ if (*prefix == NULL && uri_len == 0) {
+ return 0;
+ }
+ }
+
+ /* 1 */
+ if (xmlValidateQName((xmlChar *) qname, 0) != 0) {
+ return NAMESPACE_ERR;
+ }
+
+ /* 2 */
+ if (*prefix != NULL && uri_len == 0) {
+ return NAMESPACE_ERR;
+ }
+
+ return 0;
+}
+/* }}} */
+
+/*
+http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
+
+NAMESPACE_ERR: Raised if
+
+3. the qualifiedName has a prefix that is "xml" and the namespaceURI is different from "http://www.w3.org/XML/1998/namespace" [XML Namespaces]
+4. the qualifiedName or its prefix is "xmlns" and the namespaceURI is different from "http://www.w3.org/2000/xmlns/"
+5. the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the qualifiedName nor its prefix is "xmlns".
+*/
+
+/* {{{ xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) */
+xmlNsPtr dom_get_ns(xmlNodePtr nodep, char *uri, int *errorcode, char *prefix) {
+ xmlNsPtr nsptr = NULL;
+
+ *errorcode = 0;
+
+ if (! ((prefix && !strcmp (prefix, "xml") && strcmp(uri, (char *)XML_XML_NAMESPACE)) ||
+ (prefix && !strcmp (prefix, "xmlns") && strcmp(uri, (char *)DOM_XMLNS_NAMESPACE)) ||
+ (prefix && !strcmp(uri, (char *)DOM_XMLNS_NAMESPACE) && strcmp (prefix, "xmlns")))) {
+ nsptr = xmlNewNs(nodep, (xmlChar *)uri, (xmlChar *)prefix);
+ }
+
+ if (nsptr == NULL) {
+ *errorcode = NAMESPACE_ERR;
+ }
+
+ return nsptr;
+
+}
+/* }}} end dom_get_ns */
+
+/* {{{ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) */
+xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
+ xmlNsPtr cur;
+ xmlNs *ret = NULL;
+ if (node == NULL)
+ return NULL;
+
+ if (localName == NULL || xmlStrEqual(localName, (xmlChar *)"")) {
+ cur = node->nsDef;
+ while (cur != NULL) {
+ if (cur->prefix == NULL && cur->href != NULL) {
+ ret = cur;
+ break;
+ }
+ cur = cur->next;
+ }
+ } else {
+ cur = node->nsDef;
+ while (cur != NULL) {
+ if (cur->prefix != NULL && xmlStrEqual(localName, cur->prefix)) {
+ ret = cur;
+ break;
+ }
+ cur = cur->next;
+ }
+ }
+ return ret;
+}
+/* }}} end dom_get_nsdecl */
+
+#endif /* HAVE_DOM */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h
new file mode 100644
index 0000000..3559c4b
--- /dev/null
+++ b/ext/dom/php_dom.h
@@ -0,0 +1,165 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ | Marcus Borger <helly@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_DOM_H
+#define PHP_DOM_H
+
+extern zend_module_entry dom_module_entry;
+#define phpext_dom_ptr &dom_module_entry
+
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xinclude.h>
+#include <libxml/hash.h>
+#include <libxml/c14n.h>
+#if defined(LIBXML_HTML_ENABLED)
+#include <libxml/HTMLparser.h>
+#include <libxml/HTMLtree.h>
+#endif
+#if defined(LIBXML_XPATH_ENABLED)
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#endif
+#if defined(LIBXML_XPTR_ENABLED)
+#include <libxml/xpointer.h>
+#endif
+#ifdef PHP_WIN32
+#ifndef DOM_EXPORTS
+#define DOM_EXPORTS
+#endif
+#endif
+
+#include "xml_common.h"
+#include "ext/libxml/php_libxml.h"
+#include "zend_exceptions.h"
+#include "dom_ce.h"
+/* DOM API_VERSION, please bump it up, if you change anything in the API
+ therefore it's easier for the script-programmers to check, what's working how
+ Can be checked with phpversion("dom");
+*/
+#define DOM_API_VERSION "20031129"
+/* Define a custom type for iterating using an unused nodetype */
+#define DOM_NODESET XML_XINCLUDE_START
+
+typedef struct _dom_xpath_object {
+ zend_object std;
+ void *ptr;
+ php_libxml_ref_obj *document;
+ HashTable *prop_handler;
+ zend_object_handle handle;
+ int registerPhpFunctions;
+ HashTable *registered_phpfunctions;
+ HashTable *node_list;
+} dom_xpath_object;
+
+typedef struct _dom_nnodemap_object {
+ dom_object *baseobj;
+ int nodetype;
+ xmlHashTable *ht;
+ xmlChar *local;
+ xmlChar *ns;
+ zval *baseobjptr;
+} dom_nnodemap_object;
+
+typedef struct {
+ zend_object_iterator intern;
+ zval *curobj;
+} php_dom_iterator;
+
+#include "dom_fe.h"
+
+dom_object *dom_object_get_data(xmlNodePtr obj);
+dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document);
+zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC);
+zend_object_value dom_nnodemap_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);
+#endif
+int dom_get_strict_error(php_libxml_ref_obj *document);
+void php_dom_throw_error(int error_code, int strict_error TSRMLS_DC);
+void php_dom_throw_error_with_message(int error_code, char *error_message, int strict_error TSRMLS_DC);
+void node_list_unlink(xmlNodePtr node TSRMLS_DC);
+int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, int name_len);
+xmlNsPtr dom_get_ns(xmlNodePtr node, char *uri, int *errorcode, char *prefix);
+void dom_set_old_ns(xmlDoc *doc, xmlNs *ns);
+xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName);
+void dom_normalize (xmlNodePtr nodep TSRMLS_DC);
+xmlNode *dom_get_elements_by_tag_name_ns_raw(xmlNodePtr nodep, char *ns, char *local, int *cur, int index);
+void php_dom_create_implementation(zval **retval TSRMLS_DC);
+int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child);
+int dom_has_feature(char *feature, char *version);
+int dom_node_is_read_only(xmlNodePtr node);
+int dom_node_children_valid(xmlNodePtr node);
+void php_dom_create_interator(zval *return_value, int ce_type TSRMLS_DC);
+void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xmlHashTablePtr ht, xmlChar *local, xmlChar *ns TSRMLS_DC);
+xmlNodePtr create_notation(const xmlChar *name, const xmlChar *ExternalID, const xmlChar *SystemID);
+xmlNode *php_dom_libxml_hash_iter(xmlHashTable *ht, int index);
+xmlNode *php_dom_libxml_notation_iter(xmlHashTable *ht, int index);
+zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
+int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece, zend_class_entry *ce TSRMLS_DC);
+
+#define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \
+INIT_CLASS_ENTRY(ce, name, funcs); \
+ce.create_object = dom_objects_new; \
+entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
+
+#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern) { \
+ __intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \
+ if (__intern->ptr == NULL || !(__ptr = (__prtype)((php_libxml_node_ptr *)__intern->ptr)->node)) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
+ RETURN_NULL();\
+ } \
+}
+
+#define DOM_NO_ARGS() \
+ if (zend_parse_parameters_none() == FAILURE) { \
+ return; \
+ }
+
+#define DOM_NOT_IMPLEMENTED() \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not yet implemented"); \
+ return;
+
+#define DOM_NODELIST 0
+#define DOM_NAMEDNODEMAP 1
+
+PHP_MINIT_FUNCTION(dom);
+PHP_MSHUTDOWN_FUNCTION(dom);
+PHP_MINFO_FUNCTION(dom);
+
+#endif /* PHP_DOM_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c
new file mode 100644
index 0000000..976b693
--- /dev/null
+++ b/ext/dom/processinginstruction.c
@@ -0,0 +1,188 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_processinginstruction_construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMProcessingInstruction extends DOMNode
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1004215813
+* Since:
+*/
+
+const zend_function_entry php_dom_processinginstruction_class_functions[] = {
+ PHP_ME(domprocessinginstruction, __construct, arginfo_dom_processinginstruction_construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* {{{ proto void DOMProcessingInstruction::__construct(string name, [string value]); */
+PHP_METHOD(domprocessinginstruction, __construct)
+{
+
+ zval *id;
+ xmlNodePtr nodep = NULL, oldnode = NULL;
+ dom_object *intern;
+ char *name, *value = NULL;
+ int name_len, value_len, name_valid;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_processinginstruction_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+
+ name_valid = xmlValidateName((xmlChar *) name, 0);
+ if (name_valid != 0) {
+ php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ nodep = xmlNewPI((xmlChar *) name, (xmlChar *) value);
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMProcessingInstruction::__construct */
+
+/* {{{ target string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1478689192
+Since:
+*/
+int dom_processinginstruction_target_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr nodep;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+ ZVAL_STRING(*retval, (char *) (nodep->name), 1);
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ data string
+readonly=no
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-837822393
+Since:
+*/
+int dom_processinginstruction_data_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr nodep;
+ xmlChar *content;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ ALLOC_ZVAL(*retval);
+
+
+ if ((content = xmlNodeGetContent(nodep)) != NULL) {
+ ZVAL_STRING(*retval, content, 1);
+ xmlFree(content);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+}
+
+int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC)
+{
+ zval value_copy;
+ xmlNode *nodep;
+
+ nodep = dom_object_get_node(obj);
+
+ if (nodep == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ if (newval->type != IS_STRING) {
+ if(Z_REFCOUNT_P(newval) > 1) {
+ value_copy = *newval;
+ zval_copy_ctor(&value_copy);
+ newval = &value_copy;
+ }
+ convert_to_string(newval);
+ }
+
+ xmlNodeSetContentLen(nodep, Z_STRVAL_P(newval), Z_STRLEN_P(newval) + 1);
+
+ if (newval == &value_copy) {
+ zval_dtor(newval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/string_extend.c b/ext/dom/string_extend.c
new file mode 100644
index 0000000..2c47362
--- /dev/null
+++ b/ext/dom/string_extend.c
@@ -0,0 +1,86 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_string_extend_find_offset16, 0, 0, 1)
+ ZEND_ARG_INFO(0, offset32)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_string_extend_find_offset32, 0, 0, 1)
+ ZEND_ARG_INFO(0, offset16)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class domstringextend
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend
+* Since:
+*/
+
+const zend_function_entry php_dom_string_extend_class_functions[] = {
+ PHP_FALIAS(findOffset16, dom_string_extend_find_offset16, arginfo_dom_string_extend_find_offset16)
+ PHP_FALIAS(findOffset32, dom_string_extend_find_offset32, arginfo_dom_string_extend_find_offset32)
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ proto int dom_string_extend_find_offset16(int offset32);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset16
+Since:
+*/
+PHP_FUNCTION(dom_string_extend_find_offset16)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_string_extend_find_offset16 */
+
+/* {{{ proto int dom_string_extend_find_offset32(int offset16);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#i18n-methods-StringExtend-findOffset32
+Since:
+*/
+PHP_FUNCTION(dom_string_extend_find_offset32)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_string_extend_find_offset32 */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/tests/DOMAttr_construct_error_001.phpt b/ext/dom/tests/DOMAttr_construct_error_001.phpt
new file mode 100644
index 0000000..08734ca
--- /dev/null
+++ b/ext/dom/tests/DOMAttr_construct_error_001.phpt
@@ -0,0 +1,17 @@
+--TEST--
+DOMAttr __construct() with no arguments.
+--CREDITS--
+Josh Sweeney <jsweeney@alt-invest.net>
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$attr = new DOMAttr();
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'DOMException' with message 'DOMAttr::__construct() expects at least 1 parameter, 0 given' in %s:%d
+Stack trace:
+#0 %s(%d): DOMAttr->__construct()
+#1 {main}
+ thrown in %s on line %d
diff --git a/ext/dom/tests/DOMAttr_name_basic_001.phpt b/ext/dom/tests/DOMAttr_name_basic_001.phpt
new file mode 100644
index 0000000..29ca8c5
--- /dev/null
+++ b/ext/dom/tests/DOMAttr_name_basic_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMAttr read $name property.
+--CREDITS--
+Nic Rosental <nicrosental@gmail.com>
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$attr = new DOMAttr('category', 'books');
+print $attr->name;
+?>
+--EXPECT--
+category \ No newline at end of file
diff --git a/ext/dom/tests/DOMAttr_ownerElement_error_001.phpt b/ext/dom/tests/DOMAttr_ownerElement_error_001.phpt
new file mode 100644
index 0000000..a776654
--- /dev/null
+++ b/ext/dom/tests/DOMAttr_ownerElement_error_001.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Read $ownerElement with null parent.
+--CREDITS--
+Travis Pew
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+$attr = $root->setAttribute('category', 'books');
+$document->removeChild($root);
+$root = null;
+var_dump($attr->ownerElement);
+?>
+--EXPECTF--
+Warning: Couldn't fetch DOMAttr. Node no longer exists in %s on line %d
+
+Notice: Undefined property: DOMAttr::$ownerElement in %s on line %d
+NULL
diff --git a/ext/dom/tests/DOMAttr_value_basic_001.phpt b/ext/dom/tests/DOMAttr_value_basic_001.phpt
new file mode 100644
index 0000000..51c4ac9
--- /dev/null
+++ b/ext/dom/tests/DOMAttr_value_basic_001.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Read empty $value.
+--CREDITS--
+Jason Bouffard <jbouffard1@yahoo.com>
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$attr = new DOMAttr('category');
+print $attr->value."\n";
+?>
+===DONE===
+--EXPECTF--
+===DONE===
+
diff --git a/ext/dom/tests/DOMAttr_value_basic_002.phpt b/ext/dom/tests/DOMAttr_value_basic_002.phpt
new file mode 100644
index 0000000..384a9ca
--- /dev/null
+++ b/ext/dom/tests/DOMAttr_value_basic_002.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Write non-string $value property
+--CREDITS--
+Eric Berg <ehberg@gmail.com>
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$attr = new DOMAttr('category');
+$attr->value = 1;
+print $attr->value;
+?>
+--EXPECTF--
+1
diff --git a/ext/dom/tests/DOMCDATASection_construct_error_001.phpt b/ext/dom/tests/DOMCDATASection_construct_error_001.phpt
new file mode 100644
index 0000000..4db2130
--- /dev/null
+++ b/ext/dom/tests/DOMCDATASection_construct_error_001.phpt
@@ -0,0 +1,21 @@
+--TEST--
+__construct() with no arguments.
+--CREDITS--
+Nic Rosental nicrosental@gmail.com
+# TestFest Atlanta 2009-5-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ try
+ {
+ $section = new DOMCDataSection();
+
+ }
+ catch (Exception $e)
+ {
+ echo $e->getMessage();
+ }
+?>
+--EXPECT--
+DOMCdataSection::__construct() expects exactly 1 parameter, 0 given \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_appendData_basic.phpt b/ext/dom/tests/DOMCharacterData_appendData_basic.phpt
new file mode 100644
index 0000000..e479c1e
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_appendData_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+DOMCharacterData::appendData basic functionality test
+--CREDITS--
+Mike Sullivan <mike@regexia.com>
+#TestFest 2008 (London)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createElement('cdata');
+$root->appendChild($cdata);
+
+$cdatanode = $document->createCDATASection('');
+$cdata->appendChild($cdatanode);
+$cdatanode->appendData('data');
+echo "CDATA Length (one append): " . $cdatanode->length . "\n";
+
+$cdatanode->appendData('><&"');
+echo "CDATA Length (two appends): " . $cdatanode->length . "\n";
+
+echo "CDATA Content: " . $cdatanode->data . "\n";
+
+echo "\n" . $document->saveXML();
+
+?>
+--EXPECT--
+CDATA Length (one append): 4
+CDATA Length (two appends): 8
+CDATA Content: data><&"
+
+<?xml version="1.0"?>
+<root><cdata><![CDATA[data><&"]]></cdata></root> \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_appendData_error_001.phpt b/ext/dom/tests/DOMCharacterData_appendData_error_001.phpt
new file mode 100644
index 0000000..4126f99
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_appendData_error_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMCharacterData::appendData() with no arguments.
+--CREDITS--
+Eric Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('test');
+$root->appendChild($cdata);
+$cdata->appendData();
+?>
+--EXPECTF--
+Warning: DOMCharacterData::appendData() expects exactly 1 parameter, 0 given in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_data_basic_002.phpt b/ext/dom/tests/DOMCharacterData_data_basic_002.phpt
new file mode 100644
index 0000000..394b316
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_data_basic_002.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Create CDATA section and change it using DOMcreateCDATASection
+--CREDITS--
+Nic Rosental nicrosental@gmail.com
+# TestFest Atlanta 2009-5-28
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('t');
+$root->appendChild($cdata);
+print $document->saveXML()."\n";
+
+$cdata->data = 100;
+print $document->saveXML()."\n";
+
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<root><![CDATA[t]]></root>
+
+<?xml version="1.0"?>
+<root><![CDATA[100]]></root>
diff --git a/ext/dom/tests/DOMCharacterData_data_error_002.phpt b/ext/dom/tests/DOMCharacterData_data_error_002.phpt
new file mode 100644
index 0000000..401e0f2
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_data_error_002.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Invalid State Error when getting data on DOMCharacterData out of content.
+--CREDITS--
+Eric Berg <ehberg@gmail.com>
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$character_data = new DOMCharacterData();
+print $character_data->data;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d
diff --git a/ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt b/ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt
new file mode 100644
index 0000000..ad104f1
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_deleteData_basic_001.phpt
@@ -0,0 +1,20 @@
+--TEST--
+DOMCharacterData::deleteData() with count exceeding string size.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('test');
+$root->appendChild($cdata);
+$cdata->deleteData(1, 10);
+var_dump($cdata->data);
+?>
+--EXPECTF--
+%unicode|string%(%d) "t" \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt b/ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt
new file mode 100644
index 0000000..3fa7fba
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_deleteData_error_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMCharacterData::deleteData() with no arguments.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('test');
+$root->appendChild($cdata);
+$cdata->deleteData();
+?>
+--EXPECTF--
+Warning: DOMCharacterData::deleteData() expects exactly 2 parameters, 0 given in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt b/ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt
new file mode 100644
index 0000000..117d5de
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_deleteData_error_002.phpt
@@ -0,0 +1,23 @@
+--TEST--
+DOMCharacterData::deleteData() with offset exceeding string size.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('test');
+$root->appendChild($cdata);
+$cdata->deleteData(5, 1);
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'DOMException' with message 'Index Size Error' in %s:%d
+Stack trace:
+#0 %s(%d): DOMCharacterData->deleteData(5, 1)
+#1 {main}
+ thrown in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_insertData_error_001.phpt b/ext/dom/tests/DOMCharacterData_insertData_error_001.phpt
new file mode 100644
index 0000000..813a0be
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_insertData_error_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMCharacterData::insertData() with no arguments.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('test');
+$root->appendChild($cdata);
+$cdata->insertData();
+?>
+--EXPECTF--
+Warning: DOMCharacterData::insertData() expects exactly 2 parameters, 0 given in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_length_error_001.phpt b/ext/dom/tests/DOMCharacterData_length_error_001.phpt
new file mode 100644
index 0000000..e8bf16a
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_length_error_001.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Invalid State Error when getting length on DOMCharacterData out of content.
+--CREDITS--
+Jason Bouffard <jbouffard1@yahoo.com>
+# TestFest Atlanta 2009-05-14
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$character_data = new DOMCharacterData();
+print $character_data->length;
+?>
+===DONE===
+--EXPECTF--
+Warning: main(): Invalid State Error in %s
+===DONE===
+
diff --git a/ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt b/ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt
new file mode 100644
index 0000000..45d25dd
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_replaceData_error_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMCharacterData::replaceData() with no arguments.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('test');
+$root->appendChild($cdata);
+$cdata->replaceData();
+?>
+--EXPECTF--
+Warning: DOMCharacterData::replaceData() expects exactly 3 parameters, 0 given in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt b/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt
new file mode 100644
index 0000000..b9d73e1
--- /dev/null
+++ b/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt
@@ -0,0 +1,21 @@
+--TEST--
+__DOMCharacterData::substringData pull mid section of string
+--CREDITS--
+Nic Rosental nicrosental@gmail.com
+# TestFest Atlanta 2009-5-28
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$cdata = $document->createCDATASection('testfest');
+$root->appendChild($cdata);
+print $cdata->substringData(1, 6);
+
+?>
+--EXPECT--
+estfes \ No newline at end of file
diff --git a/ext/dom/tests/DOMComment_appendData_basic.phpt b/ext/dom/tests/DOMComment_appendData_basic.phpt
new file mode 100644
index 0000000..c756f16
--- /dev/null
+++ b/ext/dom/tests/DOMComment_appendData_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test adding data to a DOMComment
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+$comment->appendData('-more-data');
+$dom->appendChild($comment);
+$dom->saveXML();
+echo $dom->saveXML();
+
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+<!--test-comment-more-data--> \ No newline at end of file
diff --git a/ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt b/ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt
new file mode 100644
index 0000000..ae06d8a
--- /dev/null
+++ b/ext/dom/tests/DOMComment_appendData_basic_Sullivan.phpt
@@ -0,0 +1,37 @@
+--TEST--
+DOMComment::appendData basic functionality test
+--CREDITS--
+Mike Sullivan <mike@regexia.com>
+#TestFest 2008 (London)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$comment = $document->createElement('comment');
+$root->appendChild($comment);
+
+$commentnode = $document->createComment('');
+$comment->appendChild($commentnode);
+$commentnode->appendData('data');
+echo "Comment Length (one append): " . $commentnode->length . "\n";
+
+$commentnode->appendData('><&"');
+echo "Comment Length (two appends): " . $commentnode->length . "\n";
+
+echo "Comment Content: " . $commentnode->data . "\n";
+
+echo "\n" . $document->saveXML();
+
+?>
+--EXPECT--
+Comment Length (one append): 4
+Comment Length (two appends): 8
+Comment Content: data><&"
+
+<?xml version="1.0"?>
+<root><comment><!--data><&"--></comment></root> \ No newline at end of file
diff --git a/ext/dom/tests/DOMComment_construct_basic_001.phpt b/ext/dom/tests/DOMComment_construct_basic_001.phpt
new file mode 100644
index 0000000..902f7bb
--- /dev/null
+++ b/ext/dom/tests/DOMComment_construct_basic_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMComment::__construct() with constructor called twice.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DOMDocument('1.0', 'UTF-8');
+$element = $dom->appendChild(new DOMElement('root'));
+$comment = new DOMComment("This is the first comment.");
+$comment->__construct("This is the second comment.");
+$comment = $element->appendChild($comment);
+print $dom->saveXML();
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<root><!--This is the second comment.--></root>
diff --git a/ext/dom/tests/DOMComment_construct_error_001.phpt b/ext/dom/tests/DOMComment_construct_error_001.phpt
new file mode 100644
index 0000000..89142fe
--- /dev/null
+++ b/ext/dom/tests/DOMComment_construct_error_001.phpt
@@ -0,0 +1,17 @@
+--TEST--
+DOMComment::__construct() with more arguments than acceptable.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$comment = new DOMComment("comment1", "comment2");
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'DOMException' with message 'DOMComment::__construct() expects at most 1 parameter, 2 given' in %s:%d
+Stack trace:
+#0 %s(%d): DOMComment->__construct('comment1', 'comment2')
+#1 {main}
+ thrown in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMComment_insertData_basic.phpt b/ext/dom/tests/DOMComment_insertData_basic.phpt
new file mode 100644
index 0000000..5a4857d
--- /dev/null
+++ b/ext/dom/tests/DOMComment_insertData_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test inserting data into a DOMComment basic test
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+//correct offset
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+$comment->insertData(4,'-inserted');
+$dom->appendChild($comment);
+echo $dom->saveXML();
+
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+<!--test-inserted-comment-->
diff --git a/ext/dom/tests/DOMComment_insertData_error1.phpt b/ext/dom/tests/DOMComment_insertData_error1.phpt
new file mode 100644
index 0000000..56922ac
--- /dev/null
+++ b/ext/dom/tests/DOMComment_insertData_error1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test inserting data into a DOMComment basic test
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+//Negative offset
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+try {
+ $comment->insertData(-1,'-inserted');
+} catch (DOMException $e ) {
+ if ($e->getMessage() == 'Index Size Error'){
+ echo "Throws DOMException for -ve offset\n";
+ }
+}
+
+?>
+--EXPECTF--
+Throws DOMException for -ve offset
diff --git a/ext/dom/tests/DOMComment_insertData_error2.phpt b/ext/dom/tests/DOMComment_insertData_error2.phpt
new file mode 100644
index 0000000..d2affa8
--- /dev/null
+++ b/ext/dom/tests/DOMComment_insertData_error2.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test inserting data into a DOMComment basic test
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+//offset to large
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+try {
+ $comment->insertData(999,'-inserted');
+} catch (DOMException $e ) {
+ if ($e->getMessage() == 'Index Size Error'){
+ echo "Throws DOMException for offset too large\n";
+ }
+}
+
+?>
+--EXPECTF--
+Throws DOMException for offset too large \ No newline at end of file
diff --git a/ext/dom/tests/DOMComment_replaceData_basic.phpt b/ext/dom/tests/DOMComment_replaceData_basic.phpt
new file mode 100644
index 0000000..2963cb1
--- /dev/null
+++ b/ext/dom/tests/DOMComment_replaceData_basic.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Test replacing data into a DOMComment basic test
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+$comment->replaceData(4,1,'replaced');
+$dom->appendChild($comment);
+echo $dom->saveXML();
+
+// Replaces rest of string if count is greater than length of existing string
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+$comment->replaceData(0,50,'replaced');
+$dom->appendChild($comment);
+echo $dom->saveXML();
+
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+<!--testreplacedcomment-->
+<?xml version="1.0"?>
+<!--replaced-->
diff --git a/ext/dom/tests/DOMComment_replaceData_error1.phpt b/ext/dom/tests/DOMComment_replaceData_error1.phpt
new file mode 100644
index 0000000..4ae4cb6
--- /dev/null
+++ b/ext/dom/tests/DOMComment_replaceData_error1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test replacing data into a DOMComment basic test
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+//Negative offset
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+try {
+ $comment->replaceData(-1,4,'-inserted');
+} catch (DOMException $e ) {
+ if ($e->getMessage() == 'Index Size Error'){
+ echo "Throws DOMException for -ve offest\n";
+ }
+}
+
+?>
+--EXPECTF--
+Throws DOMException for -ve offest
diff --git a/ext/dom/tests/DOMComment_replaceData_error2.phpt b/ext/dom/tests/DOMComment_replaceData_error2.phpt
new file mode 100644
index 0000000..89614f9
--- /dev/null
+++ b/ext/dom/tests/DOMComment_replaceData_error2.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test replacing data into a DOMComment basic test
+--CREDITS--
+Andrew Larssen <al@larssen.org>
+London TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+//offset to large
+$dom = new DomDocument();
+$comment = $dom->createComment('test-comment');
+try {
+ $comment->replaceData(999,4,'-inserted');
+} catch (DOMException $e ) {
+ if ($e->getMessage() == 'Index Size Error'){
+ echo "Throws DOMException for offest too large\n";
+ }
+}
+
+?>
+--EXPECTF--
+Throws DOMException for offest too large \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt
new file mode 100644
index 0000000..a6f381b
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_appendXML_basic_001.phpt
@@ -0,0 +1,22 @@
+--TEST--
+DOMDocumentFragment::appendXML() with children with properties.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$fragment = $document->createDocumentFragment();
+$fragment->appendXML('<foo id="baz">bar</foo>');
+$root->appendChild($fragment);
+
+print $document->saveXML();
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<root><foo id="baz">bar</foo></root>
diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt
new file mode 100644
index 0000000..6ffe510
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_appendXML_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentFragment::appendXML() with no arguments.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$fragment = new DOMDocumentFragment();
+$fragment->appendXML();
+?>
+--EXPECTF--
+Warning: DOMDocumentFragment::appendXML() expects exactly 1 parameter, 0 given in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt
new file mode 100644
index 0000000..c02c920
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_appendXML_error_002.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMDocumentFragment::appendXML() with unbound fragment.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$fragment = new DOMDocumentFragment();
+$fragment->appendXML('<bait>crankbait</bait>');
+$document->appendChild($fragment);
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'DOMException' with message 'No Modification Allowed Error' in %s:%d
+Stack trace:
+#0 %s(%d): DOMDocumentFragment->appendXML('<bait>crankbait...')
+#1 {main}
+ thrown in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt
new file mode 100644
index 0000000..8735ae6
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_appendXML_error_003.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMDocumentFragment::appendXML() with unbalanced chunks.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$fragment = $document->createDocumentFragment();
+@$fragment->appendXML('<foo>is<bar>great</foo>');
+$root->appendChild($fragment);
+?>
+--EXPECTF--
+Warning: DOMNode::appendChild(): Document Fragment is empty in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt b/ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt
new file mode 100644
index 0000000..c82a73b
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_appendXML_hasChildNodes_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Testing DOMDocumentFragment::appendXML and DOMDocumentFragment::hasChildNodes
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doc = new DOMDocument();
+
+$fragment = $doc->createDocumentFragment();
+if ($fragment->hasChildNodes()) {
+ echo "has child nodes\n";
+} else {
+ echo "has no child nodes\n";
+}
+$fragment->appendXML('<foo>bar</foo>');
+if ($fragment->hasChildNodes()) {
+ echo "has child nodes\n";
+} else {
+ echo "has no child nodes\n";
+}
+--EXPECT--
+has no child nodes
+has child nodes
diff --git a/ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt b/ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt
new file mode 100644
index 0000000..63de771
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_construct_basic_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentFragment::__construct().
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$fragment = new DOMDocumentFragment();
+var_dump(get_class($fragment));
+?>
+--EXPECT--
+string(19) "DOMDocumentFragment"
diff --git a/ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt b/ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt
new file mode 100644
index 0000000..0d73445
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_construct_basic_002.phpt
@@ -0,0 +1,16 @@
+--TEST--
+DOMDocumentFragment::__construct() called twice.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$fragment = new DOMDocumentFragment();
+$fragment->__construct();
+var_dump($fragment);
+?>
+--EXPECTF--
+object(DOMDocumentFragment)#%d (%d) {
+}
diff --git a/ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt b/ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt
new file mode 100644
index 0000000..91173c4
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentFragment_construct_error_001.phpt
@@ -0,0 +1,17 @@
+--TEST--
+DOMDocumentFragment::__construct() with too many errors.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-24
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$fragment = new DOMDocumentFragment("root");
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'DOMException' with message 'DOMDocumentFragment::__construct() expects exactly 0 parameters, 1 given' in %s:%d
+Stack trace:
+#0 %s(%d): DOMDocumentFragment->__construct('root')
+#1 {main}
+ thrown in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_basic_001.phpt b/ext/dom/tests/DOMDocumentType_basic_001.phpt
new file mode 100644
index 0000000..8991ed9
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_basic_001.phpt
@@ -0,0 +1,48 @@
+--TEST--
+DOMDocumentType: basic access to all properties.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+// Access publicId, systemId, name, internalSubset all with values.
+$xml = '<?xml version="1.0" encoding="UTF-8" ?>';
+$xml .= '<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML//EN" "docbookx.dtd">';
+$xml .= '<chapter>1</chapter>';
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$doctype = $doc->doctype;
+print "publicId: ".$doctype->publicId."\n";
+print "systemId: ".$doctype->systemId."\n";
+print "name: ".$doctype->name."\n";
+print "internalSubset: ".$doctype->internalSubset."\n";
+
+
+// Access entities and notations with values.
+$xml = '<?xml version="1.0" encoding="UTF-8" ?>';
+$xml .= '<!DOCTYPE img [';
+$xml .= ' <!ELEMENT img EMPTY>';
+$xml .= ' <!ATTLIST img src ENTITY #REQUIRED>';
+$xml .= ' <!ENTITY logo SYSTEM "http://www.xmlwriter.net/logo.gif" NDATA gif>';
+$xml .= ' <!NOTATION gif PUBLIC "gif viewer">';
+$xml .= ']>';
+$xml .= '<img src="logo"/>';
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$doctype = $doc->doctype;
+$entities = $doctype->entities;
+$entity = $entities->item(0);
+print 'entity: '.$entity->nodeName."\n";
+$notations = $doctype->notations;
+$notation = $notations->item(0);
+print 'notation: '.$notation->nodeName."\n";
+?>
+--EXPECT--
+publicId: -//OASIS//DTD DocBook XML//EN
+systemId: docbookx.dtd
+name: chapter
+internalSubset: <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML//EN" "docbookx.dtd">
+entity: logo
+notation: gif \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_entities_error_001.phpt b/ext/dom/tests/DOMDocumentType_entities_error_001.phpt
new file mode 100644
index 0000000..73655b0
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_entities_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentType::entities with invalid state.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doctype = new DOMDocumentType();
+$entities = $doctype->entities;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt b/ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt
new file mode 100644
index 0000000..c1f7d9b
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_internalSubset_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentType::internalSubset with invalid state.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doctype = new DOMDocumentType();
+$internalSubset = $doctype->internalSubset;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_name_error_001.phpt b/ext/dom/tests/DOMDocumentType_name_error_001.phpt
new file mode 100644
index 0000000..d2426e8
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_name_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentType::name with invalid state.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doctype = new DOMDocumentType();
+$name = $doctype->name;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_notations_error_001.phpt b/ext/dom/tests/DOMDocumentType_notations_error_001.phpt
new file mode 100644
index 0000000..e4d1c3c
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_notations_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentType::notations with invalid state.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doctype = new DOMDocumentType();
+$notations = $doctype->notations;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt b/ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt
new file mode 100644
index 0000000..49a7eec
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_publicId_basic_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMDocumentType::publicId with empty value.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = '<?xml version="1.0" encoding="UTF-8" ?>';
+$xml .= '<!DOCTYPE chapter SYSTEM "http://www.xmlwriter.net/logo.gif">';
+$xml .= '<chapter>1</chapter>';
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$doctype = $doc->doctype;
+var_dump($doctype->publicId);
+?>
+--EXPECT--
+string(0) "" \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_publicId_error_001.phpt b/ext/dom/tests/DOMDocumentType_publicId_error_001.phpt
new file mode 100644
index 0000000..275bb65
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_publicId_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentType::publicId with invalid state.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doctype = new DOMDocumentType();
+$publicId = $doctype->publicId;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt b/ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt
new file mode 100644
index 0000000..56f7ddd
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_systemId_basic_001.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMDocumentType::systemId with empty value.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = '<?xml version="1.0" encoding="UTF-8" ?>';
+$xml .= '<!DOCTYPE chapter>';
+$xml .= '<chapter>1</chapter>';
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$doctype = $doc->doctype;
+var_dump($doctype->systemId);
+?>
+--EXPECT--
+string(0) "" \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocumentType_systemId_error_001.phpt b/ext/dom/tests/DOMDocumentType_systemId_error_001.phpt
new file mode 100644
index 0000000..a4aadd7
--- /dev/null
+++ b/ext/dom/tests/DOMDocumentType_systemId_error_001.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMDocumentType::systemId with invalid state.
+--CREDITS--
+Eric Lee Stewart <ericleestewart@gmail.com>
+# TestFest Atlanta 2009-05-25
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doctype = new DOMDocumentType();
+$systemId = $doctype->systemId;
+?>
+--EXPECTF--
+Warning: main(): Invalid State Error in %s on line %d \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocument_config_basic.phpt b/ext/dom/tests/DOMDocument_config_basic.phpt
new file mode 100644
index 0000000..947743a
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_config_basic.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Tests DOMDocument::config read
+--CREDITS--
+Chris Snyder <chsnyder@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+// create dom document
+$dom = new DOMDocument;
+echo "DOMDocument created\n";
+
+$test = $dom->config;
+echo "Read config:\n";
+var_dump( $test );
+
+// note -- will always be null as DOMConfiguration is not implemented in PHP
+
+echo "Done\n";
+?>
+--EXPECT--
+DOMDocument created
+Read config:
+NULL
+Done
diff --git a/ext/dom/tests/DOMDocument_createAttribute_basic.phpt b/ext/dom/tests/DOMDocument_createAttribute_basic.phpt
new file mode 100644
index 0000000..4dd181b
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createAttribute_basic.phpt
@@ -0,0 +1,26 @@
+--TEST--
+DomDocument::createAttribute() - basic test for DomDocument::createAttribute()
+--CREDITS--
+Muhammad Khalid Adnan
+# TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$node = $doc->createElement("para");
+$newnode = $doc->appendChild($node);
+
+// A pass case.
+$test_attribute = $doc->createAttribute("hahaha");
+$node->appendChild($test_attribute);
+
+echo $doc->saveXML();
+
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<para hahaha=""/>
+
diff --git a/ext/dom/tests/DOMDocument_createAttribute_error.phpt b/ext/dom/tests/DOMDocument_createAttribute_error.phpt
new file mode 100644
index 0000000..bf71d55
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createAttribute_error.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Test DOMDocument::createAttribute() for expected expection thrown when wrong parameter passed
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DOMDocument();
+
+try {
+ $attr = $dom->createAttribute(0);
+}
+catch(DOMException $e) {
+ $code = $e->getCode();
+ if(DOM_INVALID_CHARACTER_ERR === $code) {
+ echo "PASS";
+ }
+ else {
+ echo 'Wrong exception code';
+ }
+}
+catch(Exception $e) {
+ echo 'Wrong exception thrown';
+}
+
+?>
+--EXPECTF--
+PASS
diff --git a/ext/dom/tests/DOMDocument_createAttribute_error1.phpt b/ext/dom/tests/DOMDocument_createAttribute_error1.phpt
new file mode 100644
index 0000000..745873a
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createAttribute_error1.phpt
@@ -0,0 +1,29 @@
+--TEST--
+DomDocument::createAttribute() - error test for DomDocument::createAttribute()
+--CREDITS--
+Muhammad Khalid Adnan
+# TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$node = $doc->createElement("para");
+$newnode = $doc->appendChild($node);
+
+try {
+ $failed_test_attribute = $doc->createAttribute("ha haha");
+ $node->appendChild($failed_test_attribute);
+
+ echo $doc->saveXML();
+}
+catch (DOMException $e) {
+ echo 'Test failed!', PHP_EOL;
+}
+
+?>
+--EXPECT--
+Test failed!
+
diff --git a/ext/dom/tests/DOMDocument_createAttribute_variation.phpt b/ext/dom/tests/DOMDocument_createAttribute_variation.phpt
new file mode 100644
index 0000000..ff81343
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createAttribute_variation.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Test DOMDocument::createAttribute() for expected return value
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DOMDocument();
+
+$attr = $dom->createAttribute('string');
+echo get_class($attr);
+
+?>
+--EXPECTF--
+DOMAttr
diff --git a/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt b/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt
new file mode 100644
index 0000000..4f4ddf1
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMDocument::createEntityReference() should create a new entity reference node
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$dom = new DOMDocument('1.0');
+$ref = $dom->createEntityReference('nbsp');
+$dom->appendChild($ref);
+echo $dom->saveXML();
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+&nbsp;
diff --git a/ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt b/ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt
new file mode 100644
index 0000000..9f45f12
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createProcessingInstruction_basic.phpt
@@ -0,0 +1,30 @@
+--TEST--
+DomDocument::createProcessingInstruction() - basic test for DomDocument::createProcessingInstruction()
+--CREDITS--
+Muhammad Khalid Adnan
+# TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$node = $doc->createElement("para");
+$newnode = $doc->appendChild($node);
+
+$test_proc_inst0 =
+ $doc->createProcessingInstruction( "blablabla" );
+$node->appendChild($test_proc_inst0);
+
+$test_proc_inst1 =
+ $doc->createProcessingInstruction( "blablabla", "datadata" );
+$node->appendChild($test_proc_inst1);
+
+echo $doc->saveXML();
+
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<para><?blablabla?><?blablabla datadata?></para>
+
diff --git a/ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt b/ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt
new file mode 100644
index 0000000..a0c12b1
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_createProcessingInstruction_error.phpt
@@ -0,0 +1,31 @@
+--TEST--
+DomDocument::createProcessingInstruction() - error test for DomDocument::createProcessingInstruction()
+--CREDITS--
+Muhammad Khalid Adnan
+# TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$node = $doc->createElement("para");
+$newnode = $doc->appendChild($node);
+
+try {
+ $test_proc_inst =
+ $doc->createProcessingInstruction( "bla bla bla" );
+ $node->appendChild($test_proc_inst);
+
+ echo $doc->saveXML();
+}
+catch (DOMException $e)
+{
+ echo 'Test failed!', PHP_EOL;
+}
+
+?>
+--EXPECT--
+Test failed!
+
diff --git a/ext/dom/tests/DOMDocument_documentURI_basic.phpt b/ext/dom/tests/DOMDocument_documentURI_basic.phpt
new file mode 100644
index 0000000..e40a42b
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_documentURI_basic.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Tests DOMDocument::documentURI read and write
+--CREDITS--
+Chris Snyder <chsnyder@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+// create dom document
+$dom = new DOMDocument;
+$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE s1 PUBLIC "http://www.ibm.com/example.dtd" "example.dtd">
+<s1>foo</s1>';
+$dom->loadXML($xml);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+echo "DOMDocument created\n";
+
+$test = $dom->documentURI;
+echo "Read initial documentURI:\n";
+echo $test."\n";
+
+$dom->documentURI = 'http://dom.example.org/example.xml';
+$test = $dom->documentURI;
+echo "Set documentURI to a URL, reading again:\n";
+var_dump( $test );
+
+echo "Done\n";
+?>
+--EXPECTF--
+DOMDocument created
+Read initial documentURI:
+%s
+Set documentURI to a URL, reading again:
+string(34) "http://dom.example.org/example.xml"
+Done
diff --git a/ext/dom/tests/DOMDocument_encoding_basic.phpt b/ext/dom/tests/DOMDocument_encoding_basic.phpt
new file mode 100644
index 0000000..9fc099b
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_encoding_basic.phpt
@@ -0,0 +1,52 @@
+--TEST--
+DOMDocument::$encoding - read/write tests (dom_document_encoding_read/dom_document_encoding_write)
+--CREDITS--
+Hans Zaunere
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+require_once('dom_test.inc');
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+
+if( !$dom )
+{
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+echo "Empty Encoding Read: {$dom->encoding}\n";
+
+$ret = $dom->encoding = 'NYPHP DOMinatrix';
+echo "Adding invalid encoding: $ret\n";
+
+$ret = $dom->encoding = 'ISO-8859-1';
+echo "Adding ISO-8859-1 encoding: $ret\n";
+echo "ISO-8859-1 Encoding Read: {$dom->encoding}\n";
+
+$ret = $dom->encoding = 'UTF-8';
+echo "Adding UTF-8 encoding: $ret\n";
+echo "UTF-8 Encoding Read: {$dom->encoding}\n";
+
+$ret = $dom->encoding = 'UTF-16';
+echo "Adding UTF-16 encoding: $ret\n";
+echo "UTF-16 Encoding Read: {$dom->encoding}\n";
+
+
+?>
+--EXPECTF--
+Empty Encoding Read:
+
+Warning: main(): Invalid Document Encoding in %s on line %d
+Adding invalid encoding: NYPHP DOMinatrix
+Adding ISO-8859-1 encoding: ISO-8859-1
+ISO-8859-1 Encoding Read: ISO-8859-1
+Adding UTF-8 encoding: UTF-8
+UTF-8 Encoding Read: UTF-8
+Adding UTF-16 encoding: UTF-16
+UTF-16 Encoding Read: UTF-16
+
diff --git a/ext/dom/tests/DOMDocument_implementationRead_basic.phpt b/ext/dom/tests/DOMDocument_implementationRead_basic.phpt
new file mode 100644
index 0000000..17daddf
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_implementationRead_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DOMDocument::DOMImplementation - basic test for DomDocument::DOMImplementation
+--CREDITS--
+Lev Radin <prokurator@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+$doc->load(dirname(__FILE__)."/book.xml");
+
+var_dump($doc->implementation);
+
+
+?>
+--EXPECTF--
+object(DOMImplementation)#%d (0) {
+}
+
diff --git a/ext/dom/tests/DOMDocument_loadHTML_basic.phpt b/ext/dom/tests/DOMDocument_loadHTML_basic.phpt
new file mode 100644
index 0000000..616d1d8
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadHTML_basic.phpt
@@ -0,0 +1,18 @@
+--TEST--
+DOMDocument::loadHTML
+--CREDITS--
+Frank Cassedanne franck@ouarz.net
+#London TestFest 2008
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$doc = new DOMDocument();
+$doc->loadHTML("<html><body><p>Test<br></p></body></html>");
+echo $doc->saveHTML();
+?>
+--EXPECTF--
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html><body><p>Test<br></p></body></html>
diff --git a/ext/dom/tests/DOMDocument_loadHTML_error1.phpt b/ext/dom/tests/DOMDocument_loadHTML_error1.phpt
new file mode 100644
index 0000000..de8d349
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadHTML_error1.phpt
@@ -0,0 +1,15 @@
+--TEST--
+DOMDocument::loadHTML() should fail if no parameter is given
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$doc = new DOMDocument();
+$doc->loadHTML();
+?>
+--EXPECTF--
+Warning: DOMDocument::loadHTML() expects at least 1 parameter, 0 given in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_loadHTML_error2.phpt b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt
new file mode 100644
index 0000000..3167c01
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadHTML_error2.phpt
@@ -0,0 +1,15 @@
+--TEST--
+DOMDocument::loadHTML() should fail if empty string provided as input
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$doc = new DOMDocument();
+$doc->loadHTML('');
+?>
+--EXPECTF--
+Warning: DOMDocument::loadHTML(): Empty string supplied as input in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt b/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt
new file mode 100644
index 0000000..a772bc8
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+DOMDocument::$preserveWhiteSpace - test ability to read and write property
+--CREDITS--
+Lev Radin <prokurator@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+$doc->load(dirname(__FILE__)."/book.xml");
+
+var_dump($doc->preserveWhiteSpace);
+
+$doc->preserveWhiteSpace = false;
+var_dump($doc->preserveWhiteSpace);
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
+
diff --git a/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt b/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt
new file mode 100644
index 0000000..e467f56
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt
@@ -0,0 +1,40 @@
+--TEST--
+DOMDocument::$preserveWhiteSpace - test ability to read and write property
+--CREDITS--
+Lev Radin <prokurator@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+echo "Load document with preserveWhiteSpace on\n";
+$doc = new DOMDocument;
+$doc->load(dirname(__FILE__)."/book.xml");
+echo $doc->saveXML();
+
+
+echo "\nLoad document with preserveWhiteSpace off\n";
+$doc = new DOMDocument;
+$doc->preserveWhiteSpace = false;
+$doc->load(dirname(__FILE__)."/book.xml");
+echo $doc->saveXML();
+
+?>
+--EXPECT--
+Load document with preserveWhiteSpace on
+<?xml version="1.0"?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
+
+Load document with preserveWhiteSpace off
+<?xml version="1.0"?>
+<books><book><title>The Grapes of Wrath</title><author>John Steinbeck</author></book><book><title>The Pearl</title><author>John Steinbeck</author></book></books>
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt
new file mode 100644
index 0000000..93b9cf7
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_basic.phpt
@@ -0,0 +1,39 @@
+--TEST--
+DOMDocument::relaxNGValidateSource()
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$rng = <<< RNG
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <start>
+ <element name="apple">
+ <element name="pear">
+ <data type="NCName"/>
+ </element>
+ </element>
+ </start>
+</grammar>
+RNG;
+
+$good_xml = <<< GOOD_XML
+<?xml version="1.0"?>
+<apple>
+ <pear>Pear</pear>
+</apple>
+GOOD_XML;
+
+$doc = new DOMDocument();
+$doc->loadXML($good_xml);
+$result = $doc->relaxNGValidateSource($rng);
+var_dump($result);
+
+?>
+--EXPECTF--
+bool(true)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt
new file mode 100644
index 0000000..7da71a5
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error1.phpt
@@ -0,0 +1,41 @@
+--TEST--
+DOMDocument::relaxNGValidateSource() should fail if document doesn't validate
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$rng = <<< RNG
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <start>
+ <element name="apple">
+ <element name="pear">
+ <data type="NCName"/>
+ </element>
+ </element>
+ </start>
+</grammar>
+RNG;
+
+$bad_xml = <<< BAD_XML
+<?xml version="1.0"?>
+<apple>
+ <pear>Pear</pear>
+ <pear>Pear</pear>
+</apple>
+BAD_XML;
+
+$doc = new DOMDocument();
+$doc->loadXML($bad_xml);
+$result = $doc->relaxNGValidateSource($rng);
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::relaxNGValidateSource(): Did not expect element pear there in %s on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt
new file mode 100644
index 0000000..d689934
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidateSource_error2.phpt
@@ -0,0 +1,39 @@
+--TEST--
+DOMDocument::relaxNGValidateSource() should fail on invalid RNG schema
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$rng = <<< RNG
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <start>
+ <element name="apple">
+ </element>
+ </start>
+</grammar>
+RNG;
+
+$xml = <<< XML
+<?xml version="1.0"?>
+<apple>
+ <pear>Pear</pear>
+</apple>
+XML;
+
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$result = $doc->relaxNGValidateSource($rng);
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::relaxNGValidateSource(): xmlRelaxNGParseElement: element has no content in %s on line %d
+
+Warning: DOMDocument::relaxNGValidateSource(): Invalid RelaxNG in %s on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt
new file mode 100644
index 0000000..76a6442
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+DOMDocument::relaxNGValidate()
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$rng = dirname(__FILE__).'/DOMDocument_relaxNGValidate_basic.rng';
+$xml = <<< XML
+<?xml version="1.0"?>
+<apple>
+ <pear>Pear</pear>
+</apple>
+XML;
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$result = $doc->relaxNGValidate($rng);
+var_dump($result);
+?>
+--EXPECTF--
+bool(true)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng
new file mode 100644
index 0000000..35e3518
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidate_basic.rng
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <start>
+ <element name="apple">
+ <element name="pear">
+ <data type="NCName"/>
+ </element>
+ </element>
+ </start>
+</grammar>
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt
new file mode 100644
index 0000000..82957c3
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error1.phpt
@@ -0,0 +1,26 @@
+--TEST--
+DOMDocument::relaxNGValidate() should fail if document doesn't validate
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$rng = dirname(__FILE__).'/DOMDocument_relaxNGValidate_basic.rng';
+$xml = <<< XML
+<?xml version="1.0"?>
+<apple>
+ <pear>Pear</pear>
+ <pear>Pear</pear>
+</apple>
+XML;
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$result = $doc->relaxNGValidate($rng);
+var_dump($result);
+?>
+--EXPECTF--
+Warning: DOMDocument::relaxNGValidate(): Did not expect element pear there in %s on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt
new file mode 100644
index 0000000..7c5f890
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_relaxNGValidate_error2.phpt
@@ -0,0 +1,31 @@
+--TEST--
+DOMDocument::relaxNGValidate() should fail on invalid RelaxNG file source
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$rng = dirname(__FILE__).'/foo.rng';
+$xml = <<< XML
+<?xml version="1.0"?>
+<apple>
+ <pear>Pear</pear>
+ <pear>Pear</pear>
+</apple>
+XML;
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$result = $doc->relaxNGValidate($rng);
+var_dump($result);
+?>
+--EXPECTF--
+
+Warning: DOMDocument::relaxNGValidate(): I/O warning : failed to load external entity "%s/foo.rng" in %s on line %d
+
+Warning: DOMDocument::relaxNGValidate(): xmlRelaxNGParse: could not load %s/foo.rng in %s on line %d
+
+Warning: DOMDocument::relaxNGValidate(): Invalid RelaxNG in %s on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt b/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt
new file mode 100644
index 0000000..ccada3f
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Tests DOMDocument::resoleExternals get and set
+--CREDITS--
+Chris Snyder <chsnyder@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+// create dom document
+$dom = new DOMDocument;
+$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<h1>&quot;Foo&quot;</h1>';
+$dom->loadXML($xml);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+echo "DOMDocument with external entities created\n";
+
+$test = $dom->resolveExternals;
+echo "Read initial resolveExternals:\n";
+var_dump( $test );
+
+$dom->resolveExternals = TRUE;
+$test = $dom->resolveExternals;
+echo "Set resolveExternals to TRUE, reading again:\n";
+var_dump( $test );
+
+/**
+ * Don't bother testing the resolveExternals functionality here, it throws warnings on html dtd
+ *
+echo "Reloading xml with resolveExternals turned on\n";
+$dom->loadXML($xml);
+$test = $dom->saveXML();
+var_dump( $test );
+ */
+
+echo "Done";
+?>
+--EXPECT--
+DOMDocument with external entities created
+Read initial resolveExternals:
+bool(false)
+Set resolveExternals to TRUE, reading again:
+bool(true)
+Done \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt
new file mode 100644
index 0000000..dd0824b
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt
@@ -0,0 +1,29 @@
+--TEST--
+DOMDocument::saveHTMLFile() should dump the internal document into a file using HTML formatting
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$filename = dirname(__FILE__)."/tmp_savehtmlfile".time().".html";
+$doc = new DOMDocument('1.0');
+$root = $doc->createElement('html');
+$root = $doc->appendChild($root);
+$head = $doc->createElement('head');
+$head = $root->appendChild($head);
+$title = $doc->createElement('title');
+$title = $head->appendChild($title);
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+$bytes = $doc->saveHTMLFile($filename);
+var_dump($bytes);
+echo file_get_contents($filename);
+unlink($filename);
+?>
+--EXPECTF--
+int(126)
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>This is the title</title></head></html>
diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt
new file mode 100644
index 0000000..d4dfbe8
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+DOMDocument::saveHTMLFile() should fail if no parameter is given
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$doc = new DOMDocument('1.0');
+$root = $doc->createElement('html');
+$root = $doc->appendChild($root);
+$head = $doc->createElement('head');
+$head = $root->appendChild($head);
+$title = $doc->createElement('title');
+$title = $head->appendChild($title);
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+$doc->saveHTMLFile();
+?>
+--EXPECTF--
+Warning: DOMDocument::saveHTMLFile() expects exactly 1 parameter, 0 given in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt
new file mode 100644
index 0000000..33e07c6
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt
@@ -0,0 +1,15 @@
+--TEST--
+DOMDocument::saveHTMLFile() should fail if called statically
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+DOMDocument::saveHTMLFile();
+?>
+--EXPECTF--
+Fatal error: Non-static method DOMDocument::saveHTMLFile() cannot be called statically in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt
new file mode 100644
index 0000000..5aece37
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt
@@ -0,0 +1,33 @@
+--TEST--
+DOMDocument::saveHTMLFile() should format output on demand
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$filename = dirname(__FILE__)."/tmp_savehtmlfile".time().".html";
+$doc = new DOMDocument('1.0');
+$doc->formatOutput = true;
+$root = $doc->createElement('html');
+$root = $doc->appendChild($root);
+$head = $doc->createElement('head');
+$head = $root->appendChild($head);
+$title = $doc->createElement('title');
+$title = $head->appendChild($title);
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+$bytes = $doc->saveHTMLFile($filename);
+var_dump($bytes);
+echo file_get_contents($filename);
+unlink($filename);
+?>
+--EXPECTF--
+int(129)
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>This is the title</title>
+</head></html>
diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt
new file mode 100644
index 0000000..d5c6a79
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt
@@ -0,0 +1,25 @@
+--TEST--
+DOMDocument::saveHTMLFile() should fail with invalid filename
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$filename = null;
+$doc = new DOMDocument('1.0');
+$root = $doc->createElement('html');
+$root = $doc->appendChild($root);
+$head = $doc->createElement('head');
+$head = $root->appendChild($head);
+$title = $doc->createElement('title');
+$title = $head->appendChild($title);
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+$bytes = $doc->saveHTMLFile($filename);
+?>
+--EXPECTF--
+Warning: DOMDocument::saveHTMLFile(): Invalid Filename in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_saveHTML_basic.phpt b/ext/dom/tests/DOMDocument_saveHTML_basic.phpt
new file mode 100644
index 0000000..76f1ed0
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTML_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+DOMDocument::saveHTML() should dump the internal document into a string using HTML formatting
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$doc = new DOMDocument('1.0');
+$root = $doc->createElement('html');
+$root = $doc->appendChild($root);
+$head = $doc->createElement('head');
+$head = $root->appendChild($head);
+$title = $doc->createElement('title');
+$title = $head->appendChild($title);
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+echo $doc->saveHTML();
+?>
+--EXPECTF--
+<html><head><title>This is the title</title></head></html>
diff --git a/ext/dom/tests/DOMDocument_saveHTML_error2.phpt b/ext/dom/tests/DOMDocument_saveHTML_error2.phpt
new file mode 100644
index 0000000..614605b
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTML_error2.phpt
@@ -0,0 +1,15 @@
+--TEST--
+DOMDocument::saveHTML() should fail if called statically
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+DOMDocument::saveHTML(true);
+?>
+--EXPECTF--
+Fatal error: Non-static method DOMDocument::saveHTML() cannot be called statically in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_saveHTML_variant1.phpt b/ext/dom/tests/DOMDocument_saveHTML_variant1.phpt
new file mode 100644
index 0000000..d169113
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTML_variant1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+DOMDocument::saveHTML() optional parameters
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$doc = new DOMDocument('1.0');
+$root = $doc->createElement('html');
+$root = $doc->appendChild($root);
+$head = $doc->createElement('head');
+$head = $root->appendChild($head);
+$title = $doc->createElement('title');
+$title = $head->appendChild($title);
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+echo $doc->saveHTML(NULL), "\n";
+echo $doc->saveHTML($title), "\n";
+?>
+--EXPECTF--
+<html><head><title>This is the title</title></head></html>
+
+<title>This is the title</title>
diff --git a/ext/dom/tests/DOMDocument_saveHTML_variant2.phpt b/ext/dom/tests/DOMDocument_saveHTML_variant2.phpt
new file mode 100644
index 0000000..54ccda1
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_saveHTML_variant2.phpt
@@ -0,0 +1,26 @@
+--TEST--
+DOMDocument::saveHTML() vs DOMDocumet::saveXML()
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$d = new DOMDocument();
+$str = <<<EOD
+<html>
+<head>
+</head>
+<body>
+<p>Hi.<br/>there</p>
+</body>
+</html>
+EOD;
+$d->loadHTML($str);
+$e = $d->getElementsByTagName("p");
+$e = $e->item(0);
+echo $d->saveXml($e),"\n";
+echo $d->saveHtml($e),"\n";
+--EXPECTF--
+<p>Hi.<br/>there</p>
+<p>Hi.<br>there</p>
diff --git a/ext/dom/tests/DOMDocument_save_basic.phpt b/ext/dom/tests/DOMDocument_save_basic.phpt
new file mode 100644
index 0000000..c7d1ead
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_save_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+DOMDocument::save Test basic function of save method
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$doc = new DOMDocument('1.0');
+$doc->formatOutput = true;
+
+$root = $doc->createElement('book');
+
+$root = $doc->appendChild($root);
+
+$title = $doc->createElement('title');
+$title = $root->appendChild($title);
+
+$text = $doc->createTextNode('This is the title');
+$text = $title->appendChild($text);
+
+$temp_filename = dirname(__FILE__)."/DomDocument_save_basic.tmp";
+
+echo 'Wrote: ' . $doc->save($temp_filename) . ' bytes'; // Wrote: 72 bytes
+?>
+--CLEAN--
+<?php
+ $temp_filename = dirname(__FILE__)."/DomDocument_save_basic.tmp";
+ unlink($temp_filename);
+?>
+--EXPECTF--
+Wrote: 72 bytes
+
diff --git a/ext/dom/tests/DOMDocument_savexml_basic.phpt b/ext/dom/tests/DOMDocument_savexml_basic.phpt
new file mode 100644
index 0000000..10f748c
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_savexml_basic.phpt
@@ -0,0 +1,39 @@
+--TEST--
+DOM Document : save and saveXML
+--CREDITS--
+Sami Greenbury (sami@patabugen.co.uk)
+# TestFest 2008
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+
+$xml = <<< EOXML
+<?xml version="1.0" encoding="utf-8"?>
+<courses>
+ <!-- Hello World! -->
+ <aNode>
+ <childNode>
+ <childlessNode />
+ </childNode>
+ </aNode>
+</courses>
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$root = $dom->documentElement;
+$directory = dirname(__FILE__);
+
+$filename = $directory."/tmp_dom_savexml".time();
+var_dump($dom->save($filename));
+$result = file_get_contents($filename);
+var_dump($result == $dom->saveXML());
+
+unlink($filename);
+
+--EXPECTF--
+int(151)
+bool(true) \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt
new file mode 100644
index 0000000..38bc3fa
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+DomDocument::schemaValidateSource() - basic
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$xsd = file_get_contents(dirname(__FILE__)."/book.xsd");
+
+$result = $doc->schemaValidateSource($xsd);
+var_dump($result);
+
+?>
+--EXPECT--
+bool(true)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt
new file mode 100644
index 0000000..51eb82e
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt
@@ -0,0 +1,29 @@
+--TEST--
+DomDocument::schemaValidateSource() - string that is not a schema
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidateSource('string that is not a schema');
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidateSource(): Entity: line 1: parser error : Start tag expected, '<' not found in %s.php on line %d
+
+Warning: DOMDocument::schemaValidateSource(): string that is not a schema in %s.php on line %d
+
+Warning: DOMDocument::schemaValidateSource(): ^ in %s.php on line %d
+
+Warning: DOMDocument::schemaValidateSource(): Failed to parse the XML resource 'in_memory_buffer'. in %s.php on line %d
+
+Warning: DOMDocument::schemaValidateSource(): Invalid Schema in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt
new file mode 100644
index 0000000..41a833b
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt
@@ -0,0 +1,23 @@
+--TEST--
+DomDocument::schemaValidateSource() - non-conforming schema
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$xsd = file_get_contents(dirname(__FILE__)."/book-non-conforming-schema.xsd");
+
+$result = $doc->schemaValidateSource($xsd);
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidateSource(): Element 'books': No matching global declaration available for the validation root. in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt
new file mode 100644
index 0000000..93dd792
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DomDocument::schemaValidateSource() - empty string for schema string
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidateSource('');
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidateSource(): Invalid Schema source in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt
new file mode 100644
index 0000000..65c8d86
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DomDocument::schemaValidateSource() - pass no parameters
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidateSource();
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidateSource() expects exactly 1 parameter, 0 given in %s.php on line %d
+NULL
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt b/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt
new file mode 100644
index 0000000..eec790d
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt
@@ -0,0 +1,20 @@
+--TEST--
+DomDocument::schemaValidate() - basic
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidate(dirname(__FILE__)."/book.xsd");
+var_dump($result);
+
+?>
+--EXPECT--
+bool(true)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt
new file mode 100644
index 0000000..594c3c4
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt
@@ -0,0 +1,29 @@
+--TEST--
+DomDocument::schemaValidate() - file that is not a schema
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidate(dirname(__FILE__)."/book-not-a-schema.xsd");
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidate(): %sbook-not-a-schema.xsd:1: parser error : Start tag expected, '<' not found in %s.php on line %d
+
+Warning: DOMDocument::schemaValidate(): Let's see what happens upon parsing a file that doesn't contain a schema. in %s.php on line %d
+
+Warning: DOMDocument::schemaValidate(): ^ in %s.php on line %d
+
+Warning: DOMDocument::schemaValidate(): Failed to parse the XML resource '%sbook-not-a-schema.xsd'. in %s.php on line %d
+
+Warning: DOMDocument::schemaValidate(): Invalid Schema in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt
new file mode 100644
index 0000000..5ffd533
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DomDocument::schemaValidate() - non-conforming schema file
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidate(dirname(__FILE__)."/book-non-conforming-schema.xsd");
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidate(): Element 'books': No matching global declaration available for the validation root. in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt
new file mode 100644
index 0000000..275204f
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DomDocument::schemaValidate() - empty string for schema file name
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidate('');
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidate(): Invalid Schema source in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt
new file mode 100644
index 0000000..d4817de
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt
@@ -0,0 +1,21 @@
+--TEST--
+DomDocument::schemaValidate() - pass no parameters
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidate();
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidate() expects exactly 1 parameter, 0 given in %s.php on line %d
+NULL
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt
new file mode 100644
index 0000000..d3f0658
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt
@@ -0,0 +1,25 @@
+--TEST--
+DomDocument::schemaValidate() - non-existant schema file
+--CREDITS--
+Daniel Convissor <danielc@php.net>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book.xml");
+
+$result = $doc->schemaValidate(dirname(__FILE__)."/non-existant-file");
+var_dump($result);
+
+?>
+--EXPECTF--
+Warning: DOMDocument::schemaValidate(): I/O warning : failed to load external entity "%snon-existant-file" in %s.php on line %d
+
+Warning: DOMDocument::schemaValidate(): Failed to locate the main schema resource at '%s/non-existant-file'. in %s.php on line %d
+
+Warning: DOMDocument::schemaValidate(): Invalid Schema in %s.php on line %d
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_standalone_basic.phpt b/ext/dom/tests/DOMDocument_standalone_basic.phpt
new file mode 100644
index 0000000..2316a38
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_standalone_basic.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Tests DOMDocument::standalone get, set, and functionality
+--CREDITS--
+Chris Snyder <chsnyder@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+// create dom document
+$dom = new DOMDocument;
+$xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE s1 PUBLIC "http://www.ibm.com/example.dtd" "example.dtd">
+<s1>foo</s1>';
+$dom->loadXML($xml);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+echo "Standalone DOMDocument created\n";
+
+$test = $dom->standalone;
+echo "Read initial standalone:\n";
+var_dump( $test );
+
+$dom->standalone = FALSE;
+$test = $dom->standalone;
+echo "Set standalone to FALSE, reading again:\n";
+var_dump( $test );
+
+$test = $dom->saveXML();
+echo "Document is no longer standalone\n";
+var_dump( $test );
+
+echo "Done";
+?>
+--EXPECT--
+Standalone DOMDocument created
+Read initial standalone:
+bool(true)
+Set standalone to FALSE, reading again:
+bool(false)
+Document is no longer standalone
+string(136) "<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE s1 PUBLIC "http://www.ibm.com/example.dtd" "example.dtd">
+<s1>foo</s1>
+"
+Done \ No newline at end of file
diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt
new file mode 100644
index 0000000..9ad55a4
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+DomDocument::$strictErrorChecking - basic test
+--CREDITS--
+Vincent Tsao <notes4vincent@gmail.com>
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+$doc->load(dirname(__FILE__)."/book.xml");
+
+var_dump($doc->strictErrorChecking);
+
+$doc->strictErrorChecking = false;
+var_dump($doc->strictErrorChecking);
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt
new file mode 100644
index 0000000..b6d94f9
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt
@@ -0,0 +1,59 @@
+--TEST--
+DomDocument::$strictErrorChecking - ensure turning off actually works
+--CREDITS--
+Vincent Tsao <notes4vincent@gmail.com>
+(and Dan Convissor)
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+echo "Load document\n";
+$doc = new DOMDocument;
+$doc->load(dirname(__FILE__)."/book.xml");
+
+echo "See if strictErrorChecking is on\n";
+var_dump($doc->strictErrorChecking);
+
+echo "Should throw DOMException when strictErrorChecking is on\n";
+try {
+ $attr = $doc->createAttribute(0);
+} catch (DOMException $e) {
+ echo "GOOD. DOMException thrown\n";
+ echo $e->getMessage() ."\n";
+} catch (Exception $e) {
+ echo "OOPS. Other exception thrown\n";
+}
+
+
+echo "Turn strictErrorChecking off\n";
+$doc->strictErrorChecking = false;
+
+echo "See if strictErrorChecking is off\n";
+var_dump($doc->strictErrorChecking);
+
+echo "Should raise PHP error because strictErrorChecking is off\n";
+try {
+ $attr = $doc->createAttribute(0);
+} catch (DOMException $e) {
+ echo "OOPS. DOMException thrown\n";
+ echo $e->getMessage() ."\n";
+} catch (Exception $e) {
+ echo "OOPS. Other exception thrown\n";
+}
+
+?>
+--EXPECTF--
+Load document
+See if strictErrorChecking is on
+bool(true)
+Should throw DOMException when strictErrorChecking is on
+GOOD. DOMException thrown
+Invalid Character Error
+Turn strictErrorChecking off
+See if strictErrorChecking is off
+bool(false)
+Should raise PHP error because strictErrorChecking is off
+
+Warning: DOMDocument::createAttribute(): Invalid Character Error in %sDOMDocument_strictErrorChecking_variation.php on line %d
diff --git a/ext/dom/tests/DOMDocument_validate_basic.phpt b/ext/dom/tests/DOMDocument_validate_basic.phpt
new file mode 100644
index 0000000..7c0eec8
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_validate_basic.phpt
@@ -0,0 +1,31 @@
+--TEST--
+DOMDocument::validate() should validate an internal DTD declaration
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$xml = "<?xml version=\"1.0\"?>
+<!DOCTYPE note [
+<!ELEMENT note (to,from,heading,body)>
+<!ELEMENT to (#PCDATA)>
+<!ELEMENT from (#PCDATA)>
+<!ELEMENT heading (#PCDATA)>
+<!ELEMENT body (#PCDATA)>
+]>
+<note>
+<to>Tove</to>
+<from>Jani</from>
+<heading>Reminder</heading>
+<body>Don't forget me this weekend</body>
+</note>";
+$dom = new DOMDocument('1.0');
+$dom->loadXML($xml);
+var_dump($dom->validate());
+?>
+--EXPECTF--
+bool(true)
diff --git a/ext/dom/tests/DOMDocument_validate_error1.phpt b/ext/dom/tests/DOMDocument_validate_error1.phpt
new file mode 100644
index 0000000..8e1e72f
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_validate_error1.phpt
@@ -0,0 +1,16 @@
+--TEST--
+DOMDocument::validate() should fail if any parameter is given
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+$dom = new DOMDocument('1.0');
+$dom->validate(true);
+?>
+--EXPECTF--
+Warning: DOMDocument::validate() expects exactly 0 parameters, 1 given in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_validate_error2.phpt b/ext/dom/tests/DOMDocument_validate_error2.phpt
new file mode 100644
index 0000000..fe7e4fc
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_validate_error2.phpt
@@ -0,0 +1,15 @@
+--TEST--
+DOMDocument::validate() should fail if called statically
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+DOMDocument::validate();
+?>
+--EXPECTF--
+Fatal error: Non-static method DOMDocument::validate() cannot be called statically in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_validate_external_dtd.phpt b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt
new file mode 100644
index 0000000..51a044c
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMDocument::validate() should validate an external DTD declaration
+--CREDITS--
+Knut Urdalen <knut@php.net>
+#PHPTestFest2009 Norway 2009-06-09 \o/
+--SKIPIF--
+<?php
+require_once dirname(__FILE__) .'/skipif.inc';
+?>
+--FILE--
+<?php
+// reusing existing xml: http://cvs.php.net/viewvc.cgi/php-src/ext/dom/tests/dom.xml?view=co&content-type=text%2Fplain
+// reusing existing dtd: http://cvs.php.net/viewvc.cgi/php-src/ext/dom/tests/dom.ent?view=co&content-type=text%2Fplain
+$dom = new DOMDocument('1.0');
+$dom->load(dirname(__FILE__).'/dom.xml');
+var_dump($dom->validate());
+?>
+--EXPECTF--
+bool(true)
diff --git a/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt b/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt
new file mode 100644
index 0000000..a95b0a3
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt
@@ -0,0 +1,38 @@
+--TEST--
+DOMDocument::$validateOnParse - read/write tests (dom_document_validate_on_parse_read/dom_document_validate_on_parse_write)
+--CREDITS--
+Hans Zaunere
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+require_once('dom_test.inc');
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+
+if( !$dom )
+{
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+echo "Checking documented default value: ";
+var_dump($dom->validateOnParse);
+
+$dom->validateOnParse = TRUE;
+echo "Setting validateOnParse to TRUE: ";
+var_dump($dom->validateOnParse);
+
+$dom->validateOnParse = FALSE;
+echo "Setting validateOnParse to FALSE: ";
+var_dump($dom->validateOnParse);
+
+?>
+--EXPECT--
+Checking documented default value: bool(false)
+Setting validateOnParse to TRUE: bool(true)
+Setting validateOnParse to FALSE: bool(false)
+
diff --git a/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt b/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt
new file mode 100644
index 0000000..d0cea29
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt
@@ -0,0 +1,46 @@
+--TEST--
+DOMDocument::$validateOnParse - effectual determination (dom_document_validate_on_parse_read/dom_document_validate_on_parse_write)
+--CREDITS--
+Hans Zaunere
+# TestFest 2009 NYPHP
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+
+require_once('dom_test.inc');
+
+chdir(__DIR__);
+$XMLStringGood = file_get_contents('note.xml');
+
+$dom = new DOMDocument;
+$dom->resolveExternals = TRUE;
+
+$dom->validateOnParse = FALSE;
+echo "validateOnParse set to FALSE: \n";
+$dom->loadXML($XMLStringGood);
+echo "No Error Report Above\n";
+
+$BogusElement = $dom->createElement('NYPHP','DOMinatrix');
+$Body = $dom->getElementsByTagName('from')->item(0);
+$Body->appendChild($BogusElement);
+$XMLStringBad = $dom->saveXML();
+
+echo "validateOnParse set to TRUE: \n";
+$dom->validateOnParse = TRUE;
+$dom->loadXML($XMLStringBad);
+echo "Error Report Above\n";
+
+?>
+--EXPECTF--
+validateOnParse set to FALSE:
+No Error Report Above
+validateOnParse set to TRUE:
+
+Warning: DOMDocument::loadXML(): No declaration for element NYPHP in Entity, line: %d in %s on line %d
+
+Warning: DOMDocument::loadXML(): Element from was declared #PCDATA but contains non text nodes in Entity, line: %d in %s on line %d
+Error Report Above
+
diff --git a/ext/dom/tests/DOMElement_hasAttributes_basic.phpt b/ext/dom/tests/DOMElement_hasAttributes_basic.phpt
new file mode 100644
index 0000000..8e804be
--- /dev/null
+++ b/ext/dom/tests/DOMElement_hasAttributes_basic.phpt
@@ -0,0 +1,49 @@
+--TEST--
+DOMNode: hasAttributes()
+--CREDITS--
+James Lewis <james@s-1.com>
+#TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$element = $dom->documentElement;
+
+echo "Verify that we have a DOMElement object:\n";
+echo get_class($element), "\n";
+
+echo "\nElement should have attributes:\n";
+var_dump($element->hasAttributes());
+
+$nodelist=$dom->getElementsByTagName('tbody') ;
+$element = $nodelist->item(0);
+
+echo "\nVerify that we have a DOMElement object:\n";
+echo get_class($element), "\n";
+
+echo "\nElement should have no attributes:\n";
+var_dump($element->hasAttributes());
+
+
+?>
+--EXPECTF--
+Verify that we have a DOMElement object:
+DOMElement
+
+Element should have attributes:
+bool(true)
+
+Verify that we have a DOMElement object:
+DOMElement
+
+Element should have no attributes:
+bool(false)
diff --git a/ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt b/ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt
new file mode 100644
index 0000000..3b19ea4
--- /dev/null
+++ b/ext/dom/tests/DOMImplementation_createDocumentType_basic.phpt
@@ -0,0 +1,18 @@
+--TEST--
+DOMImplementation::createDocumentType()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$imp = new DOMImplementation();
+$doctype = $imp->createDocumentType("html",
+ "-//W3C//DTD XHTML 1.0 Strict//EN",
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
+$doc = $imp->createDocument(null, 'html', $doctype);
+echo $doc->saveHTML();
+?>
+--EXPECTF--
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html></html>
diff --git a/ext/dom/tests/DOMImplementation_createDocument_basic.phpt b/ext/dom/tests/DOMImplementation_createDocument_basic.phpt
new file mode 100644
index 0000000..78d20ae
--- /dev/null
+++ b/ext/dom/tests/DOMImplementation_createDocument_basic.phpt
@@ -0,0 +1,14 @@
+--TEST--
+DOMImplementation::createDocument()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$x = new DOMImplementation();
+$doc = $x->createDocument(null, 'html');
+echo $doc->saveHTML();
+?>
+--EXPECTF--
+<html></html>
diff --git a/ext/dom/tests/DOMImplementation_hasFeature_basic.phpt b/ext/dom/tests/DOMImplementation_hasFeature_basic.phpt
new file mode 100644
index 0000000..b53e912
--- /dev/null
+++ b/ext/dom/tests/DOMImplementation_hasFeature_basic.phpt
@@ -0,0 +1,15 @@
+--TEST--
+DOMImplementation::hasFeature()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$imp = new DOMImplementation();
+var_dump($imp->hasFeature('Core', '1.0'));
+var_dump($imp->hasFeature('XML', '2.0'));
+?>
+--EXPECTF--
+bool(true)
+bool(true)
diff --git a/ext/dom/tests/DOMNode_C14NFile_basic.phpt b/ext/dom/tests/DOMNode_C14NFile_basic.phpt
new file mode 100644
index 0000000..6af6e3e
--- /dev/null
+++ b/ext/dom/tests/DOMNode_C14NFile_basic.phpt
@@ -0,0 +1,38 @@
+--TEST--
+DOMNode::C14NFile()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$xml = <<< XML
+<?xml version="1.0" ?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
+XML;
+
+$output = dirname(__FILE__).'/DOMNode_C14NFile_basic.tmp';
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$node = $doc->getElementsByTagName('title')->item(0);
+var_dump($node->C14NFile($output));
+$content = file_get_contents($output);
+var_dump($content);
+?>
+--CLEAN--
+<?php
+$output = dirname(__FILE__).'/DOMNode_C14NFile_basic.tmp';
+unlink($output);
+?>
+--EXPECTF--
+int(34)
+string(34) "<title>The Grapes of Wrath</title>"
diff --git a/ext/dom/tests/DOMNode_C14N_basic.phpt b/ext/dom/tests/DOMNode_C14N_basic.phpt
new file mode 100644
index 0000000..52a47a1
--- /dev/null
+++ b/ext/dom/tests/DOMNode_C14N_basic.phpt
@@ -0,0 +1,29 @@
+--TEST--
+DOMNode::C14N()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$xml = <<< XML
+<?xml version="1.0" ?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
+XML;
+
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+$node = $doc->getElementsByTagName('title')->item(0);
+var_dump($node->C14N());
+?>
+--EXPECTF--
+string(34) "<title>The Grapes of Wrath</title>"
diff --git a/ext/dom/tests/DOMNode_cloneNode_basic.phpt b/ext/dom/tests/DOMNode_cloneNode_basic.phpt
new file mode 100644
index 0000000..cba3c17
--- /dev/null
+++ b/ext/dom/tests/DOMNode_cloneNode_basic.phpt
@@ -0,0 +1,106 @@
+--TEST--
+DOM cloneNode : Basic Functionality
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--CREDITS--
+Simon Hughes <odbc3@hotmail.com>
+--FILE--
+<?php
+
+$xml = <<< EOXML
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<courses>
+ <course title="one">
+ <notes>
+ <note>c1n1</note>
+ <note>c1n2</note>
+ </notes>
+ </course>
+ <course title="two">
+ <notes>
+ <note>c2n1</note>
+ <note>c2n2</note>
+ </notes>
+ </course>
+</courses>
+EOXML;
+
+function dumpcourse($current) {
+ $title = ($current->nodeType != XML_TEXT_NODE && $current->hasAttribute('title')) ? $current->getAttribute('title'):"no title";
+ echo "Course: $title:";echo(get_class($current)), "\n";
+ echo "~";var_dump($current->textContent);
+}
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$root = $dom->documentElement;
+
+// strip all text nodes from this tree
+$children = $root->childNodes;
+$len = $children->length;
+for ($index = $children->length - 1; $index >=0; $index--) {
+ $current = $children->item($index);
+ if ($current->nodeType == XML_TEXT_NODE) {
+ $noderemoved = $root->removeChild($current);
+ }
+}
+
+echo "Start cloneNode test\n";
+$first_course = $children->item(0);
+$cloned_first_course_default = $first_course->cloneNode();
+$first_course->setAttribute('title', 'new title1');
+
+$cloned_first_course_true = $first_course->cloneNode(true);
+$first_course->setAttribute('title', 'new title2');
+
+$cloned_first_course_false = $first_course->cloneNode(false);
+$first_course->setAttribute('title', 'new title3');
+
+$cloned_first_course_default->setAttribute('title', 'new title default');
+$cloned_first_course_true->setAttribute('title', 'new title true');
+$cloned_first_course_false->setAttribute('title', 'new title false');
+
+$root->appendChild($cloned_first_course_default);
+$root->appendChild($cloned_first_course_true);
+$root->appendChild($cloned_first_course_false);
+
+$children = $root->childNodes;
+for ($index = 0; $index < $children->length; $index++) {
+ echo "node $index\n";
+ dumpcourse($children->item($index));
+}
+
+--EXPECTF--
+Start cloneNode test
+node 0
+Course: new title3:DOMElement
+~string(24) "
+
+ c1n1
+ c1n2
+
+ "
+node 1
+Course: two:DOMElement
+~string(24) "
+
+ c2n1
+ c2n2
+
+ "
+node 2
+Course: new title default:DOMElement
+~string(0) ""
+node 3
+Course: new title true:DOMElement
+~string(24) "
+
+ c1n1
+ c1n2
+
+ "
+node 4
+Course: new title false:DOMElement
+~string(0) ""
diff --git a/ext/dom/tests/DOMNode_getLineNo_basic.phpt b/ext/dom/tests/DOMNode_getLineNo_basic.phpt
new file mode 100644
index 0000000..3f57681
--- /dev/null
+++ b/ext/dom/tests/DOMNode_getLineNo_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMNode::getLineNo()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$file = dirname(__FILE__).'/book.xml';
+$doc = new DOMDocument();
+$doc->load($file);
+$nodes = $doc->getElementsByTagName('title');
+foreach($nodes as $node) {
+ var_dump($node->getLineNo());
+}
+?>
+--EXPECTF--
+int(4)
+int(8)
diff --git a/ext/dom/tests/DOMNode_getNodePath_basic.phpt b/ext/dom/tests/DOMNode_getNodePath_basic.phpt
new file mode 100644
index 0000000..7c14ffa
--- /dev/null
+++ b/ext/dom/tests/DOMNode_getNodePath_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+DOMNode::getNodePath()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+$file = dirname(__FILE__).'/book.xml';
+$doc = new DOMDocument();
+$doc->load($file);
+$nodes = $doc->getElementsByTagName('title');
+foreach($nodes as $node) {
+ var_dump($node->getNodePath());
+}
+?>
+--EXPECTF--
+string(20) "/books/book[1]/title"
+string(20) "/books/book[2]/title"
diff --git a/ext/dom/tests/DOMNode_hasChildNodes.phpt b/ext/dom/tests/DOMNode_hasChildNodes.phpt
new file mode 100644
index 0000000..5c1d714
--- /dev/null
+++ b/ext/dom/tests/DOMNode_hasChildNodes.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Tests DOMNode::hasChildNodes()
+--CREDITS--
+Michael Stillwell <mjs@beebo.org>
+# TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$dom = new DOMDocument();
+
+$dom->loadXML('<root/>');
+
+echo $dom->saveXML();
+
+echo "Document has child nodes\n";
+var_dump($dom->documentElement->hasChildNodes());
+
+echo "Document has child nodes\n";
+$dom->loadXML('<root><a/></root>');
+var_dump($dom->documentElement->hasChildNodes());
+
+echo "Remove node and save\n";
+$dom->documentElement->removeChild($dom->documentElement->firstChild);
+echo $dom->saveXML();
+
+echo "Document has child nodes\n";
+var_dump($dom->documentElement->hasChildNodes());
+
+echo "Document with 2 child nodes\n";
+$dom->loadXML('<root><a/><b/></root>');
+var_dump($dom->documentElement->hasChildNodes());
+
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+<root/>
+Document has child nodes
+bool(false)
+Document has child nodes
+bool(true)
+Remove node and save
+<?xml version="1.0"?>
+<root/>
+Document has child nodes
+bool(false)
+Document with 2 child nodes
+bool(true)
diff --git a/ext/dom/tests/DOMNode_hasChildNodes_basic.phpt b/ext/dom/tests/DOMNode_hasChildNodes_basic.phpt
new file mode 100644
index 0000000..3a6f6b4
--- /dev/null
+++ b/ext/dom/tests/DOMNode_hasChildNodes_basic.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Test whether a node has child nodes: hasChildNodes()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+
+/* Create an XML document
+ * with strcuture
+ * <book>
+ * <title>This is the title</title>
+ * </book>
+ * Check for child nodes of the <book>, <title> and This is the title
+ *
+*/
+
+$doc = new DOMDocument();
+
+$root = $doc->createElement('book');
+$doc->appendChild($root);
+
+$title = $doc->createElement('title');
+$root->appendChild($title);
+
+$text = $doc->createTextNode('This is the title');
+$title->appendChild($text);
+
+echo "Root has child nodes: ";
+var_dump($root->hasChildNodes());
+
+echo "Title has child nodes: ";
+var_dump($title->hasChildNodes());
+
+echo "Text has child nodes: ";
+var_dump($text->hasChildNodes());
+
+?>
+--EXPECTF--
+Root has child nodes: bool(true)
+Title has child nodes: bool(true)
+Text has child nodes: bool(false) \ No newline at end of file
diff --git a/ext/dom/tests/DOMNode_insertBefore.phpt b/ext/dom/tests/DOMNode_insertBefore.phpt
new file mode 100644
index 0000000..d371aaf
--- /dev/null
+++ b/ext/dom/tests/DOMNode_insertBefore.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Tests DOMNode::insertBefore()
+--CREDITS--
+Michael Stillwell <mjs@beebo.org>
+# TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$dom = new DOMDocument();
+$dom->loadXML('<root/>');
+echo $dom->saveXML();
+
+$e1 = $dom->createElement("A");
+$e2 = $dom->documentElement->appendChild($dom->createElement("B"));
+
+echo "Add new node B\n";
+echo $dom->saveXML();
+
+echo "Add new node A before B\n";
+$e2->parentNode->insertBefore($e1, $e2);
+echo $dom->saveXML();
+
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+<root/>
+Add new node B
+<?xml version="1.0"?>
+<root><B/></root>
+Add new node A before B
+<?xml version="1.0"?>
+<root><A/><B/></root>
diff --git a/ext/dom/tests/DOMNode_insertBefore_error1.phpt b/ext/dom/tests/DOMNode_insertBefore_error1.phpt
new file mode 100644
index 0000000..d655479
--- /dev/null
+++ b/ext/dom/tests/DOMNode_insertBefore_error1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+DOMNode::insertBefore() should fail if node belongs to another document
+--CREDITS--
+Knut Urdalen <knut@php.net>
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc1 = new DOMDocument();
+$doc2 = new DOMDocument();
+
+$node_in_doc1 = $doc1->createElement("foo");
+$node_in_doc2 = $doc2->createElement("bar");
+
+try {
+ $node_in_doc2->insertBefore($node_in_doc1);
+} catch(DOMException $e) {
+ echo $e->getMessage();
+}
+
+?>
+--EXPECTF--
+Wrong Document Error
diff --git a/ext/dom/tests/DOMNode_issamenode_basic.phpt b/ext/dom/tests/DOMNode_issamenode_basic.phpt
new file mode 100644
index 0000000..e008340
--- /dev/null
+++ b/ext/dom/tests/DOMNode_issamenode_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+DOMNode: isSameNode()
+--CREDITS--
+James Lewis <james@s-1.com>
+#TestFest 2008
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$node = $dom->documentElement;
+if($node->isSameNode($node))
+ echo "EXPECTING SAME NODE, PASSED\n" ;
+else
+ echo "EXPECTING SAME NODE, FAILED\n" ;
+
+$nodelist=$dom->getElementsByTagName('tbody') ;
+
+if($nodelist->item(0)->isSameNode($node))
+ echo "EXPECTING NOT SAME NODE, FAILED\n" ;
+else
+ echo "EXPECTING NOT SAME NODE, PASSED\n" ;
+
+?>
+===DONE===
+--EXPECT--
+EXPECTING SAME NODE, PASSED
+EXPECTING NOT SAME NODE, PASSED
+===DONE===
diff --git a/ext/dom/tests/DOMNode_normalize_basic.phpt b/ext/dom/tests/DOMNode_normalize_basic.phpt
new file mode 100644
index 0000000..e413fb0
--- /dev/null
+++ b/ext/dom/tests/DOMNode_normalize_basic.phpt
@@ -0,0 +1,64 @@
+--TEST--
+DOMNode::normalize()
+--SKIPIF--
+<?php
+include('skipif.inc');
+?>
+--FILE--
+<?php
+
+/* Create an XML document
+ * with structure
+ * <book>
+ * <author></author>
+ * <title>This is the title</title>
+ * </book>
+ * Calculate the number of title text nodes (1).
+ * Add another text node to title. Calculate the number of title text nodes (2).
+ * Normalize author. Calculate the number of title text nodes (2).
+ * Normalize title. Calculate the number of title text nodes (1).
+*/
+
+$doc = new DOMDocument();
+
+$root = $doc->createElement('book');
+$doc->appendChild($root);
+
+$title = $doc->createElement('title');
+$root->appendChild($title);
+
+$author = $doc->createElement('author');
+$root->appendChild($author);
+
+$text = $doc->createTextNode('This is the first title');
+$title->appendChild($text);
+
+echo "Number of child nodes of title = ";
+var_dump($title->childNodes->length);
+
+// add a second text node to title
+$text = $doc->createTextNode('This is the second title');
+$title->appendChild($text);
+
+echo "Number of child nodes of title after adding second title = ";
+var_dump($title->childNodes->length);
+
+// should do nothing
+$author->normalize();
+
+echo "Number of child nodes of title after normalizing author = ";
+var_dump($title->childNodes->length);
+
+
+// should concatenate first and second title text nodes
+$title->normalize();
+
+echo "Number of child nodes of title after normalizing title = ";
+var_dump($title->childNodes->length);
+
+?>
+--EXPECTF--
+Number of child nodes of title = int(1)
+Number of child nodes of title after adding second title = int(2)
+Number of child nodes of title after normalizing author = int(2)
+Number of child nodes of title after normalizing title = int(1) \ No newline at end of file
diff --git a/ext/dom/tests/DOMNode_removeChild_basic.phpt b/ext/dom/tests/DOMNode_removeChild_basic.phpt
new file mode 100644
index 0000000..384eb47
--- /dev/null
+++ b/ext/dom/tests/DOMNode_removeChild_basic.phpt
@@ -0,0 +1,106 @@
+--TEST--
+DOM removeChild : Basic Functionality
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--CREDITS--
+Simon Hughes <odbc3@hotmail.com>
+--FILE--
+<?php
+
+$xml = <<< EOXML
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<courses>
+ <course title="one">
+ <notes>
+ <note>c1n1</note>
+ <note>c1n2</note>
+ </notes>
+ </course>
+ <course title="two">
+ <notes>
+ <note>c2n1</note>
+ <note>c2n2</note>
+ </notes>
+ </course>
+</courses>
+EOXML;
+
+function dumpcourse($current) {
+ $title = ($current->nodeType != XML_TEXT_NODE && $current->hasAttribute('title')) ? $current->getAttribute('title'):"no title";
+ echo "Course: $title:";echo get_class($current), "\n";
+ echo "~";var_dump($current->textContent);
+}
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$root = $dom->documentElement;
+
+$children = $root->childNodes;
+$len = $children->length;
+echo "orignal has $len nodes\n";
+for ($index = $children->length - 1; $index >=0; $index--) {
+ echo "node $index\n";
+ $current = $children->item($index);
+ dumpcourse($current);
+ if ($current->nodeType == XML_TEXT_NODE) {
+ $noderemoved = $root->removeChild($current);
+ }
+}
+$children = $root->childNodes;
+$len = $children->length;
+echo "after text removed it now has $len nodes\n";
+for ($index = 0; $index < $children->length; $index++) {
+ echo "node $index\n";
+ $current = $children->item($index);
+ dumpcourse($current);
+}
+
+--EXPECTF--
+orignal has 5 nodes
+node 4
+Course: no title:DOMText
+~string(1) "
+"
+node 3
+Course: two:DOMElement
+~string(24) "
+
+ c2n1
+ c2n2
+
+ "
+node 2
+Course: no title:DOMText
+~string(2) "
+ "
+node 1
+Course: one:DOMElement
+~string(24) "
+
+ c1n1
+ c1n2
+
+ "
+node 0
+Course: no title:DOMText
+~string(2) "
+ "
+after text removed it now has 2 nodes
+node 0
+Course: one:DOMElement
+~string(24) "
+
+ c1n1
+ c1n2
+
+ "
+node 1
+Course: two:DOMElement
+~string(24) "
+
+ c2n1
+ c2n2
+
+ "
diff --git a/ext/dom/tests/DOMNode_replaceChild_basic.phpt b/ext/dom/tests/DOMNode_replaceChild_basic.phpt
new file mode 100644
index 0000000..49fc055
--- /dev/null
+++ b/ext/dom/tests/DOMNode_replaceChild_basic.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Replacing a child node
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--CREDITS--
+Matt Raines <matt@raines.me.uk>
+#London TestFest 2008
+--FILE--
+<?php
+$document = new DOMDocument();
+$document->loadXML('<?xml version="1.0" encoding="utf-8"?>
+<root><foo><bar/><baz/></foo><spam><eggs/><eggs/></spam></root>');
+
+// Replaces the child node oldChild with newChild in the list of children, and
+// returns the oldChild node.
+$parent = $document->getElementsByTagName('foo')->item(0);
+$new_child = $document->createElement('qux');
+$old_child = $parent->replaceChild($new_child, $parent->firstChild);
+echo "New child replaces old child:\n" . $document->saveXML();
+echo "Old child is returned:\n" . $old_child->tagName . "\n";
+
+// If the newChild is already in the tree, it is first removed.
+$parent = $document->getElementsByTagName('spam')->item(0);
+$parent->replaceChild($new_child, $parent->firstChild);
+echo "Existing child is removed from tree:\n" . $document->saveXML();
+
+// Children are inserted in the correct order.
+$new_child = $document->getElementsByTagName('spam')->item(0);
+$parent = $document->getElementsByTagName('foo')->item(0);
+$parent->replaceChild($new_child, $parent->firstChild);
+echo "Children are inserted in order:\n" . $document->saveXML();
+?>
+--EXPECT--
+New child replaces old child:
+<?xml version="1.0" encoding="utf-8"?>
+<root><foo><qux/><baz/></foo><spam><eggs/><eggs/></spam></root>
+Old child is returned:
+bar
+Existing child is removed from tree:
+<?xml version="1.0" encoding="utf-8"?>
+<root><foo><baz/></foo><spam><qux/><eggs/></spam></root>
+Children are inserted in order:
+<?xml version="1.0" encoding="utf-8"?>
+<root><foo><spam><qux/><eggs/></spam></foo></root>
diff --git a/ext/dom/tests/DOMText_appendData_basic.phpt b/ext/dom/tests/DOMText_appendData_basic.phpt
new file mode 100644
index 0000000..0eea699
--- /dev/null
+++ b/ext/dom/tests/DOMText_appendData_basic.phpt
@@ -0,0 +1,40 @@
+--TEST--
+DOMText::appendData basic functionality test
+--CREDITS--
+Mike Sullivan <mike@regexia.com>
+#TestFest 2008 (London)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$document = new DOMDocument;
+$root = $document->createElement('root');
+$document->appendChild($root);
+
+$text = $document->createElement('text');
+$root->appendChild($text);
+
+$textnode = $document->createTextNode('');
+$text->appendChild($textnode);
+$textnode->appendData('data');
+echo "Text Length (one append): " . $textnode->length . "\n";
+
+$textnode->appendData('><&"');
+echo "Text Length (two appends): " . $textnode->length . "\n";
+
+echo "Text Content: " . $textnode->data . "\n";
+
+echo "\n" . $document->saveXML();
+
+?>
+===DONE===
+--EXPECT--
+Text Length (one append): 4
+Text Length (two appends): 8
+Text Content: data><&"
+
+<?xml version="1.0"?>
+<root><text>data&gt;&lt;&amp;"</text></root>
+===DONE===
+ \ No newline at end of file
diff --git a/ext/dom/tests/book-non-conforming-schema.xsd b/ext/dom/tests/book-non-conforming-schema.xsd
new file mode 100755
index 0000000..d1ecbef
--- /dev/null
+++ b/ext/dom/tests/book-non-conforming-schema.xsd
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="make_it_fail">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="book" minOccurs="1" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="title" type="xs:string"/>
+ <xs:element name="author" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/ext/dom/tests/book-not-a-schema.xsd b/ext/dom/tests/book-not-a-schema.xsd
new file mode 100755
index 0000000..d89e3bb
--- /dev/null
+++ b/ext/dom/tests/book-not-a-schema.xsd
@@ -0,0 +1 @@
+Let's see what happens upon parsing a file that doesn't contain a schema.
diff --git a/ext/dom/tests/book.xml b/ext/dom/tests/book.xml
new file mode 100644
index 0000000..95de0da
--- /dev/null
+++ b/ext/dom/tests/book.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/book.xml.gz b/ext/dom/tests/book.xml.gz
new file mode 100644
index 0000000..2c97807
--- /dev/null
+++ b/ext/dom/tests/book.xml.gz
Binary files differ
diff --git a/ext/dom/tests/book.xsd b/ext/dom/tests/book.xsd
new file mode 100755
index 0000000..45986fc
--- /dev/null
+++ b/ext/dom/tests/book.xsd
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="books">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="book" minOccurs="1" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="title" type="xs:string"/>
+ <xs:element name="author" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/ext/dom/tests/bug28721.phpt b/ext/dom/tests/bug28721.phpt
new file mode 100644
index 0000000..464498e
--- /dev/null
+++ b/ext/dom/tests/bug28721.phpt
@@ -0,0 +1,485 @@
+--TEST--
+Bug #28721 (appendChild() and insertBefore() unset DOMText)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function print_node(DomNode $node) {
+ echo "name (value): " . $node->nodeName . " (" . $node->nodeValue . ")\n";
+}
+
+function print_node_r(DomNode $node) {
+ static $indent = "";
+ echo "\n" . $indent;
+ print_node($node);
+
+ echo $indent . "parent: ";
+ if ( $node->parentNode )
+ print_node($node->parentNode);
+ else
+ echo "NULL\n";
+
+ echo $indent . "previousSibling: ";
+ if ( $node->previousSibling )
+ print_node($node->previousSibling);
+ else
+ echo "NULL\n";
+
+ echo $indent . "nextSibling: ";
+ if ( $node->nextSibling )
+ print_node($node->nextSibling);
+ else
+ echo "NULL\n";
+
+ if ( !$node->hasChildNodes() )
+ return;
+
+ foreach ($node->childNodes as $child) {
+
+ $old_indent = $indent;
+ $indent .= " ";
+ print_node_r($child);
+ $indent = $old_indent;
+ }
+}
+
+function err_handler($errno, $errstr, $errfile, $errline) {
+ echo "Error ($errno) on line $errline: $errstr\n";
+}
+
+// Record 'DocumentFragment is empty' warnings
+set_error_handler("err_handler", E_WARNING);
+
+$xml = new DomDocument();
+
+$p = $xml->createElement("p");
+
+$p->appendChild($t1 = $xml->createTextNode(" t1 "));
+$p->appendChild($b = $xml->createElement("b"));
+$b->appendChild($xml->createTextNode("X"));
+$p->appendChild($t2 = $xml->createTextNode(" t2 "));
+$p->appendChild($xml->createTextNode(" xxx "));
+
+print_node_r($p);
+
+echo "\nAppend t1 to p:\n";
+$ret = $p->appendChild($t1);
+
+print_node_r($p);
+echo "\n";
+
+echo "t1 == ret: ";
+var_dump( $t1 === $ret );
+
+
+$d = $xml->createElement("div");
+$d->appendChild($t3 = $xml->createTextNode(" t3 "));
+$d->appendChild($b = $xml->createElement("b"));
+$b->appendChild($xml->createElement("X"));
+$d->appendChild($t4 = $xml->createTextNode(" t4 "));
+$d->appendChild($xml->createTextNode(" xxx "));
+
+echo "\ndiv:\n";
+print_node_r($d);
+
+echo "\nInsert t4 before t3:\n";
+
+$ret = $d->insertBefore($t4, $t3);
+
+print_node_r($d);
+echo "\n";
+
+$frag = $xml->createDocumentFragment();
+
+$t5 = $frag->appendChild($xml->createTextNode(" t5 "));
+$frag->appendChild($i = $xml->createElement("i"));
+$i->appendChild($xml->createTextNode(" frob "));
+$frag->appendChild($xml->createTextNOde(" t6 "));
+
+echo "\np:\n";
+print_node_r($p);
+echo "\nFragment:\n";
+print_node_r($frag);
+
+echo "\nAppending fragment to p:\n";
+$p->appendChild($frag);
+
+print_node_r($p);
+echo "\nFragment:\n";
+print_node_r($frag);
+
+echo "\ndiv:\n";
+print_node_r($d);
+echo "\nInserting fragment before t4\n";
+$d->insertBefore($frag, $t4);
+print_node_r($d);
+
+echo "\np:\n";
+print_node_r($p);
+
+?>
+--EXPECT--
+
+name (value): p ( t1 X t2 xxx )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): #text ( t1 )
+ parent: name (value): p ( t1 X t2 xxx )
+ previousSibling: NULL
+ nextSibling: name (value): b (X)
+
+ name (value): b (X)
+ parent: name (value): p ( t1 X t2 xxx )
+ previousSibling: name (value): #text ( t1 )
+ nextSibling: name (value): #text ( t2 )
+
+ name (value): #text (X)
+ parent: name (value): b (X)
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t2 )
+ parent: name (value): p ( t1 X t2 xxx )
+ previousSibling: name (value): b (X)
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): #text ( xxx )
+ parent: name (value): p ( t1 X t2 xxx )
+ previousSibling: name (value): #text ( t2 )
+ nextSibling: NULL
+
+Append t1 to p:
+
+name (value): p (X t2 xxx t1 )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): b (X)
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t2 )
+
+ name (value): #text (X)
+ parent: name (value): b (X)
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t2 )
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: name (value): b (X)
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): #text ( xxx )
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: name (value): #text ( t2 )
+ nextSibling: name (value): #text ( t1 )
+
+ name (value): #text ( t1 )
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: name (value): #text ( xxx )
+ nextSibling: NULL
+
+t1 == ret: bool(true)
+
+div:
+
+name (value): div ( t3 t4 xxx )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): #text ( t3 )
+ parent: name (value): div ( t3 t4 xxx )
+ previousSibling: NULL
+ nextSibling: name (value): b ()
+
+ name (value): b ()
+ parent: name (value): div ( t3 t4 xxx )
+ previousSibling: name (value): #text ( t3 )
+ nextSibling: name (value): #text ( t4 )
+
+ name (value): X ()
+ parent: name (value): b ()
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t4 )
+ parent: name (value): div ( t3 t4 xxx )
+ previousSibling: name (value): b ()
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): #text ( xxx )
+ parent: name (value): div ( t3 t4 xxx )
+ previousSibling: name (value): #text ( t4 )
+ nextSibling: NULL
+
+Insert t4 before t3:
+
+name (value): div ( t4 t3 xxx )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): #text ( t4 )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t3 )
+
+ name (value): #text ( t3 )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): #text ( t4 )
+ nextSibling: name (value): b ()
+
+ name (value): b ()
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): #text ( t3 )
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): X ()
+ parent: name (value): b ()
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( xxx )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): b ()
+ nextSibling: NULL
+
+
+p:
+
+name (value): p (X t2 xxx t1 )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): b (X)
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t2 )
+
+ name (value): #text (X)
+ parent: name (value): b (X)
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t2 )
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: name (value): b (X)
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): #text ( xxx )
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: name (value): #text ( t2 )
+ nextSibling: name (value): #text ( t1 )
+
+ name (value): #text ( t1 )
+ parent: name (value): p (X t2 xxx t1 )
+ previousSibling: name (value): #text ( xxx )
+ nextSibling: NULL
+
+Fragment:
+
+name (value): #document-fragment ()
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): #text ( t5 )
+ parent: name (value): #document-fragment ()
+ previousSibling: NULL
+ nextSibling: name (value): i ( frob )
+
+ name (value): i ( frob )
+ parent: name (value): #document-fragment ()
+ previousSibling: name (value): #text ( t5 )
+ nextSibling: name (value): #text ( t6 )
+
+ name (value): #text ( frob )
+ parent: name (value): i ( frob )
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t6 )
+ parent: name (value): #document-fragment ()
+ previousSibling: name (value): i ( frob )
+ nextSibling: NULL
+
+Appending fragment to p:
+
+name (value): p (X t2 xxx t1 t5 frob t6 )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): b (X)
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t2 )
+
+ name (value): #text (X)
+ parent: name (value): b (X)
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t2 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): b (X)
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): #text ( xxx )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( t2 )
+ nextSibling: name (value): #text ( t1 )
+
+ name (value): #text ( t1 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( xxx )
+ nextSibling: name (value): #text ( t5 )
+
+ name (value): #text ( t5 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( t1 )
+ nextSibling: name (value): i ( frob )
+
+ name (value): i ( frob )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( t5 )
+ nextSibling: name (value): #text ( t6 )
+
+ name (value): #text ( frob )
+ parent: name (value): i ( frob )
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t6 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): i ( frob )
+ nextSibling: NULL
+
+Fragment:
+
+name (value): #document-fragment ()
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+div:
+
+name (value): div ( t4 t3 xxx )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): #text ( t4 )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t3 )
+
+ name (value): #text ( t3 )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): #text ( t4 )
+ nextSibling: name (value): b ()
+
+ name (value): b ()
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): #text ( t3 )
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): X ()
+ parent: name (value): b ()
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( xxx )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): b ()
+ nextSibling: NULL
+
+Inserting fragment before t4
+Error (2) on line 109: DOMNode::insertBefore(): Document Fragment is empty
+
+name (value): div ( t4 t3 xxx )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): #text ( t4 )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t3 )
+
+ name (value): #text ( t3 )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): #text ( t4 )
+ nextSibling: name (value): b ()
+
+ name (value): b ()
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): #text ( t3 )
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): X ()
+ parent: name (value): b ()
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( xxx )
+ parent: name (value): div ( t4 t3 xxx )
+ previousSibling: name (value): b ()
+ nextSibling: NULL
+
+p:
+
+name (value): p (X t2 xxx t1 t5 frob t6 )
+parent: NULL
+previousSibling: NULL
+nextSibling: NULL
+
+ name (value): b (X)
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: NULL
+ nextSibling: name (value): #text ( t2 )
+
+ name (value): #text (X)
+ parent: name (value): b (X)
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t2 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): b (X)
+ nextSibling: name (value): #text ( xxx )
+
+ name (value): #text ( xxx )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( t2 )
+ nextSibling: name (value): #text ( t1 )
+
+ name (value): #text ( t1 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( xxx )
+ nextSibling: name (value): #text ( t5 )
+
+ name (value): #text ( t5 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( t1 )
+ nextSibling: name (value): i ( frob )
+
+ name (value): i ( frob )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): #text ( t5 )
+ nextSibling: name (value): #text ( t6 )
+
+ name (value): #text ( frob )
+ parent: name (value): i ( frob )
+ previousSibling: NULL
+ nextSibling: NULL
+
+ name (value): #text ( t6 )
+ parent: name (value): p (X t2 xxx t1 t5 frob t6 )
+ previousSibling: name (value): i ( frob )
+ nextSibling: NULL
diff --git a/ext/dom/tests/bug28817.phpt b/ext/dom/tests/bug28817.phpt
new file mode 100644
index 0000000..a250bff
--- /dev/null
+++ b/ext/dom/tests/bug28817.phpt
@@ -0,0 +1,38 @@
+--TEST--
+Bug #28817 (properties in extended class)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+class z extends domDocument{
+ /** variable can have name */
+ public $p_array;
+ public $p_variable;
+
+ function __construct(){
+ $this->p_array[] = 'bonus';
+ $this->p_array[] = 'vir';
+ $this->p_array[] = 'semper';
+ $this->p_array[] = 'tiro';
+
+ $this->p_variable = 'Cessante causa cessat effectus';
+ }
+}
+
+$z=new z();
+var_dump($z->p_array);
+var_dump($z->p_variable);
+?>
+--EXPECTF--
+array(4) {
+ [0]=>
+ string(5) "bonus"
+ [1]=>
+ string(3) "vir"
+ [2]=>
+ string(6) "semper"
+ [3]=>
+ string(4) "tiro"
+}
+string(30) "Cessante causa cessat effectus"
diff --git a/ext/dom/tests/bug32615.phpt b/ext/dom/tests/bug32615.phpt
new file mode 100644
index 0000000..c6f2b5b
--- /dev/null
+++ b/ext/dom/tests/bug32615.phpt
@@ -0,0 +1,84 @@
+--TEST--
+Bug #32615 (Replacing and inserting Fragments)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DomDocument;
+$frag = $dom->createDocumentFragment();
+$frag->appendChild(new DOMElement('root'));
+$dom->appendChild($frag);
+$root = $dom->documentElement;
+
+$frag->appendChild(new DOMElement('first'));
+$root->appendChild($frag);
+
+$frag->appendChild(new DOMElement('second'));
+$root->appendChild($frag);
+
+$node = $dom->createElement('newfirst');
+$frag->appendChild($node);
+$root->replaceChild($frag, $root->firstChild);
+
+unset($frag);
+$frag = $dom->createDocumentFragment();
+
+$frag->appendChild(new DOMElement('newsecond'));
+$root->replaceChild($frag, $root->lastChild);
+
+$node = $frag->appendChild(new DOMElement('fourth'));
+$root->insertBefore($frag, NULL);
+
+$frag->appendChild(new DOMElement('third'));
+$node = $root->insertBefore($frag, $node);
+
+$frag->appendChild(new DOMElement('start'));
+$root->insertBefore($frag, $root->firstChild);
+
+$frag->appendChild(new DOMElement('newthird'));
+$root->replaceChild($frag, $node);
+
+$frag->appendChild(new DOMElement('newfourth'));
+$root->replaceChild($frag, $root->lastChild);
+
+$frag->appendChild(new DOMElement('first'));
+$root->replaceChild($frag, $root->firstChild->nextSibling);
+
+$root->removeChild($root->firstChild);
+
+echo $dom->saveXML()."\n";
+
+while ($root->hasChildNodes()) {
+ $root->removeChild($root->firstChild);
+}
+
+$frag->appendChild(new DOMElement('first'));
+$root->insertBefore($frag, $root->firstChild);
+
+$node = $frag->appendChild(new DOMElement('fourth'));
+$root->appendChild($frag);
+
+$frag->appendChild(new DOMElement('second'));
+$frag->appendChild(new DOMElement('third'));
+$root->insertBefore($frag, $node);
+
+echo $dom->saveXML()."\n";
+
+$frag = $dom->createDocumentFragment();
+$root = $dom->documentElement;
+$root->replaceChild($frag, $root->firstChild);
+
+echo $dom->saveXML();
+
+?>
+--EXPECT--
+
+<?xml version="1.0"?>
+<root><first/><newsecond/><newthird/><newfourth/></root>
+
+<?xml version="1.0"?>
+<root><first/><second/><third/><fourth/></root>
+
+<?xml version="1.0"?>
+<root><second/><third/><fourth/></root>
+
diff --git a/ext/dom/tests/bug34276.phpt b/ext/dom/tests/bug34276.phpt
new file mode 100644
index 0000000..6959d90
--- /dev/null
+++ b/ext/dom/tests/bug34276.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Bug #34276 (setAttributeNS and default namespace)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<<HERE
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<foo xmlns="http://www.example.com/ns/foo"
+ xmlns:fubar="http://www.example.com/ns/fubar" attra="attra" />
+HERE;
+
+function dump($elems) {
+ foreach ($elems as $elem) {
+ var_dump($elem->nodeName);
+ dump($elem->childNodes);
+ }
+}
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$foo = $dom->documentElement;
+var_dump($foo->hasAttributeNS('http://www.example.com/ns/foo', 'attra'));
+var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attra'));
+
+$foo->setAttributeNS('http://www.example.com/ns/foo', 'attra', 'attranew');
+$foo->setAttributeNS('http://www.example.com/ns/fubar', 'attrb', 'attrbnew');
+$foo->setAttributeNS('http://www.example.com/ns/foo', 'attrc', 'attrc');
+
+var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attra'));
+var_dump($foo->getAttributeNS('http://www.example.com/ns/fubar', 'attrb'));
+var_dump($foo->getAttributeNS('http://www.example.com/ns/foo', 'attrc'));
+
+print $dom->saveXML();
+?>
+--EXPECT--
+bool(false)
+string(0) ""
+string(8) "attranew"
+string(8) "attrbnew"
+string(5) "attrc"
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<foo xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:default="http://www.example.com/ns/foo" attra="attra" default:attra="attranew" fubar:attrb="attrbnew" default:attrc="attrc"/>
diff --git a/ext/dom/tests/bug35342.phpt b/ext/dom/tests/bug35342.phpt
new file mode 100644
index 0000000..f93c062
--- /dev/null
+++ b/ext/dom/tests/bug35342.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #35342 (isset(DOMNodeList->length) returns false)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DOMDocument();
+$dom->loadXML("<root><foo>foobar</foo><foo>foobar#2</foo></root>");
+
+$nodelist = $dom->getElementsByTagName("foo");
+
+var_dump($nodelist->length, isset($nodelist->length), isset($nodelist->foo));
+var_dump(empty($nodelist->length), empty($nodelist->foo));
+?>
+--EXPECT--
+int(2)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
diff --git a/ext/dom/tests/bug35673.phpt b/ext/dom/tests/bug35673.phpt
new file mode 100644
index 0000000..a29ae96
--- /dev/null
+++ b/ext/dom/tests/bug35673.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #35673 (formatOutput does not work with saveHTML).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$html = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>This is the title</title></head></html>';
+
+$htmldoc = new DOMDocument();
+$htmldoc->loadHTML($html);
+$htmldoc->formatOutput = true;
+echo $htmldoc->saveHTML();
+?>
+--EXPECT--
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>This is the title</title>
+</head></html>
diff --git a/ext/dom/tests/bug36756.phpt b/ext/dom/tests/bug36756.phpt
new file mode 100644
index 0000000..4e47b86
--- /dev/null
+++ b/ext/dom/tests/bug36756.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #36756 (DOMDocument::removeChild corrupts node)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+/* Node is preserved from removeChild */
+$dom = new DOMDocument();
+$dom->loadXML('<root><child/></root>');
+$xpath = new DOMXpath($dom);
+$node = $xpath->query('/root')->item(0);
+echo $node->nodeName . "\n";
+$dom->removeChild($GLOBALS['dom']->firstChild);
+echo "nodeType: " . $node->nodeType . "\n";
+
+/* Node gets destroyed during removeChild */
+$dom->loadXML('<root><child/></root>');
+$xpath = new DOMXpath($dom);
+$node = $xpath->query('//child')->item(0);
+echo $node->nodeName . "\n";
+$GLOBALS['dom']->removeChild($GLOBALS['dom']->firstChild);
+
+echo "nodeType: " . $node->nodeType . "\n";
+
+?>
+--EXPECTF--
+root
+nodeType: 1
+child
+
+Warning: Couldn't fetch DOMElement. Node no longer exists in %sbug36756.php on line %d
+
+Notice: Undefined property: DOMElement::$nodeType in %sbug36756.php on line %d
+nodeType:
diff --git a/ext/dom/tests/bug37277.phpt b/ext/dom/tests/bug37277.phpt
new file mode 100644
index 0000000..112b9f4
--- /dev/null
+++ b/ext/dom/tests/bug37277.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #37277 (cloning Dom Documents or Nodes does not work)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom1 = new DomDocument('1.0', 'UTF-8');
+
+$xml = '<foo />';
+$dom1->loadXml($xml);
+
+$node = clone $dom1->documentElement;
+
+$dom2 = new DomDocument('1.0', 'UTF-8');
+$dom2->appendChild($dom2->importNode($node->cloneNode(true), TRUE));
+
+print $dom2->saveXML();
+
+
+?>
+--EXPECT--
+
+<?xml version="1.0" encoding="UTF-8"?>
+<foo/>
+
diff --git a/ext/dom/tests/bug37456.phpt b/ext/dom/tests/bug37456.phpt
new file mode 100644
index 0000000..5f0fc28
--- /dev/null
+++ b/ext/dom/tests/bug37456.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #37456 (DOMElement->setAttribute() loops forever)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument();
+$doc->resolveExternals = true;
+$doc->load(dirname(__FILE__)."/dom.xml");
+
+$root = $doc->getElementsByTagName('foo')->item(0);
+$root->setAttribute('bar', '&gt;');
+$attr = $root->setAttribute('bar', 'newval');
+print $attr->nodeValue;
+
+
+?>
+--EXPECT--
+
+newval
+
diff --git a/ext/dom/tests/bug38438.phpt b/ext/dom/tests/bug38438.phpt
new file mode 100644
index 0000000..f512528
--- /dev/null
+++ b/ext/dom/tests/bug38438.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Bug #38438 (DOMNodeList->item(0) segfault on empty NodeList)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$list = new DOMNodeList();
+var_dump($list->item(0));
+echo "OK\n";
+?>
+--EXPECT--
+NULL
+OK
diff --git a/ext/dom/tests/bug38474.phpt b/ext/dom/tests/bug38474.phpt
new file mode 100644
index 0000000..54226ef
--- /dev/null
+++ b/ext/dom/tests/bug38474.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Bug #38474 (getAttribute select attribute by order, even when prefixed) (OK to fail with libxml2 < 2.6.2x)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+if (version_compare(LIBXML_DOTTED_VERSION, "2.6.20", "<")) {
+ print "skip libxml version " . LIBXML_DOTTED_VERSION;
+}
+?>
+--FILE--
+<?php
+$xml = '<node xmlns:pre="http://foo.com/tr/pre"
+ xmlns:post="http://foo.com/tr/post"
+ pre:type="bar" type="foo" ><sub /></node>';
+$dom = new DomDocument();
+$dom->loadXML($xml);
+echo $dom->firstChild->getAttribute('type')."\n";
+echo $dom->firstChild->getAttribute('pre:type')."\n";
+
+$dom->firstChild->setAttribute('pre:type', 'bar2');
+$dom->firstChild->setAttribute('type', 'foo2');
+$dom->firstChild->setAttribute('post:type', 'baz');
+$dom->firstChild->setAttribute('new:type', 'baz2');
+
+echo $dom->firstChild->getAttribute('type')."\n";
+echo $dom->firstChild->getAttribute('pre:type')."\n";
+echo $dom->firstChild->getAttribute('post:type')."\n";
+
+$dom->firstChild->removeAttribute('pre:type');
+$dom->firstChild->removeAttribute('type');
+
+echo $dom->firstChild->getAttribute('type')."\n";
+echo $dom->firstChild->getAttribute('pre:type')."\n";
+echo $dom->firstChild->getAttribute('post:type')."\n";
+echo $dom->firstChild->getAttribute('new:type');
+?>
+--EXPECT--
+foo
+bar
+foo2
+bar2
+baz
+
+
+baz
+baz2
diff --git a/ext/dom/tests/bug38850.phpt b/ext/dom/tests/bug38850.phpt
new file mode 100644
index 0000000..b0de90b
--- /dev/null
+++ b/ext/dom/tests/bug38850.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #38850 (lookupNamespaceURI does not return default namespace)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<<HERE
+<?xml version="1.0" ?>
+<foo xmlns="http://www.example.com/ns/foo" />
+HERE;
+
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+
+$root = $doc->documentElement;
+
+print $root->lookupNamespaceURI(NULL);
+
+
+?>
+--EXPECT--
+http://www.example.com/ns/foo
diff --git a/ext/dom/tests/bug38949.phpt b/ext/dom/tests/bug38949.phpt
new file mode 100644
index 0000000..4c81d9b
--- /dev/null
+++ b/ext/dom/tests/bug38949.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #38949 (Cannot get xmlns value attribute)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument();
+$doc->load(dirname(__FILE__)."/nsdoc.xml");
+
+$root = $doc->documentElement;
+
+echo $root->getAttribute("xmlns")."\n";
+echo $root->getAttribute("xmlns:ns2")."\n";
+
+$child = $root->firstChild->nextSibling;
+echo $child->getAttribute("xmlns")."\n";
+echo $child->getAttribute("xmlns:ns2")."\n";
+
+echo "DONE\n";
+?>
+--EXPECT--
+http://ns
+http://ns2
+
+
+DONE
diff --git a/ext/dom/tests/bug40836.phpt b/ext/dom/tests/bug40836.phpt
new file mode 100644
index 0000000..b96b39c
--- /dev/null
+++ b/ext/dom/tests/bug40836.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #40836 (Segfault in insertBefore)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DOMDocument("1.0", "UTF-8");
+$dom->preserveWhiteSpace = false;
+$xml = (binary)'<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <entry xmlns="http://www.w3.org/2005/Atom">
+ <updated>2007-02-14T00:00:00+01:00</updated>
+ <content>
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <p>paragraph</p>
+ </div>
+ </content>
+ </entry>
+</feed>';
+$dom->loadXML($xml);
+$entry = $dom->getElementsByTagNameNS("http://www.w3.org/2005/Atom", "entry")->item(0);
+$contentNode = $entry->getElementsByTagName("content")->item(0)->firstChild;
+$dateNode = $entry->getElementsByTagName("updated")->item(0)->firstChild;
+$contentNode->firstChild->insertBefore($dateNode);
+echo $dom->saveXML();
+?>
+--EXPECT--
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"><entry xmlns="http://www.w3.org/2005/Atom"><updated/><content><div xmlns="http://www.w3.org/1999/xhtml"><p>paragraph2007-02-14T00:00:00+01:00</p></div></content></entry></feed>
diff --git a/ext/dom/tests/bug41257.phpt b/ext/dom/tests/bug41257.phpt
new file mode 100644
index 0000000..edf62a5
--- /dev/null
+++ b/ext/dom/tests/bug41257.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #41257 (lookupNamespaceURI does not work as expected)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument();
+$doc->load(dirname(__FILE__)."/nsdoc.xml");
+
+$root = $doc->documentElement;
+
+$duri = $doc->lookupNamespaceURI("ns2")."\n";
+$euri = $root->lookupNamespaceURI("ns2")."\n";
+
+var_dump($duri == $euri);
+
+$dpref = $doc->lookupPrefix("http://ns2")."\n";
+$epref = $root->lookupPrefix("http://ns2")."\n";
+
+var_dump($dpref == $epref);
+
+$disdef = $doc->isDefaultNamespace("http://ns")."\n";
+$eisdef = $root->isDefaultNamespace("http://ns")."\n";
+
+var_dump($dpref === $epref);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/dom/tests/bug41374.phpt b/ext/dom/tests/bug41374.phpt
new file mode 100644
index 0000000..21fc345
--- /dev/null
+++ b/ext/dom/tests/bug41374.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Bug #41374 (wholetext concats values of wrong nodes)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = (binary)<<<EOXML
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<root>foo<child />baz</root>
+EOXML;
+
+$doc = new DOMDocument();
+$doc->loadXML($xml);
+
+$root = $doc->documentElement;
+$foo = $root->firstChild;
+
+var_dump($foo->wholeText == "foo");
+
+$bar = $root->insertBefore($doc->createTextNode("bar"), $foo->nextSibling);
+
+var_dump($foo->wholeText == "foobar");
+var_dump($foo->wholeText == $bar->wholeText);
+$baz = $bar->nextSibling->nextSibling;
+
+var_dump($baz->wholeText === $foo->wholeText);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(false)
diff --git a/ext/dom/tests/bug42082.phpt b/ext/dom/tests/bug42082.phpt
new file mode 100644
index 0000000..b5fc893
--- /dev/null
+++ b/ext/dom/tests/bug42082.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #42082 (NodeList length zero should be empty)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doc = new DOMDocument();
+$xpath = new DOMXPath($doc);
+$nodes = $xpath->query('*');
+echo get_class($nodes), "\n";
+var_dump($nodes->length);
+$length = $nodes->length;
+var_dump(empty($nodes->length), empty($length));
+
+$doc->loadXML("<element></element>");
+var_dump($doc->firstChild->nodeValue, empty($doc->firstChild->nodeValue), isset($doc->firstChild->nodeValue));
+var_dump(empty($doc->nodeType), empty($doc->firstChild->nodeType))
+?>
+===DONE===
+--EXPECTF--
+DOMNodeList
+int(0)
+bool(true)
+bool(true)
+string(0) ""
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+===DONE===
+
diff --git a/ext/dom/tests/bug43364.phpt b/ext/dom/tests/bug43364.phpt
new file mode 100644
index 0000000..6e08ffc
--- /dev/null
+++ b/ext/dom/tests/bug43364.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Bug #43364 (recursive xincludes don't remove internal xml nodes properly)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function loopElements($nodes)
+{
+ $count = 0;
+ foreach($nodes as $node) {
+ if($node instanceof DOMElement) {
+ $count++;
+ if($node->childNodes->length > 0) {
+ $count += loopElements($node->childNodes);
+ }
+ }
+ }
+ return $count;
+}
+
+$xml = <<<DOC
+<?xml version="1.0" encoding="UTF-8"?>
+<root xmlns:xi="http://www.w3.org/2001/XInclude">
+ <a>
+ <a_child1>ac1</a_child1>
+ <a_child2>ac2</a_child2>
+ </a>
+ <b><xi:include xpointer="xpointer(/root/a)" /></b>
+ <c><xi:include xpointer="xpointer(/root/b)" /></c>
+</root>
+DOC;
+
+$doc = new DomDocument();
+$doc->loadXml($xml);
+$doc->xinclude();
+
+$count = loopElements(array($doc->documentElement));
+
+var_dump($count);
+?>
+--EXPECT--
+int(13)
diff --git a/ext/dom/tests/bug44648.phpt b/ext/dom/tests/bug44648.phpt
new file mode 100644
index 0000000..d04f590
--- /dev/null
+++ b/ext/dom/tests/bug44648.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Bug #44648 (Attribute names not checked for wellformedness)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument();
+$doc->loadXML('<root/>');
+
+$root = $doc->documentElement;
+
+try {
+ $attr = new DOMAttr('@acb', '123');
+ $root->setAttributeNode($attr);
+} catch (DOMException $e) {
+ echo $e->getMessage()."\n";
+}
+
+try {
+ $root->setAttribute('@def', '456');
+} catch (DOMException $e) {
+ echo $e->getMessage()."\n";
+}
+
+try {
+ $root->setAttributeNS(NULL, '@ghi', '789');
+} catch (DOMException $e) {
+ echo $e->getMessage()."\n";
+}
+
+try {
+ $root->setAttributeNS('urn::test', 'a:g@hi', '789');
+} catch (DOMException $e) {
+ echo $e->getMessage()."\n";
+}
+
+echo $doc->saveXML($root);
+?>
+--EXPECT--
+Invalid Character Error
+Invalid Character Error
+Invalid Character Error
+Namespace Error
+<root/> \ No newline at end of file
diff --git a/ext/dom/tests/bug45251.phpt b/ext/dom/tests/bug45251.phpt
new file mode 100644
index 0000000..652e3b2
--- /dev/null
+++ b/ext/dom/tests/bug45251.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #45251 (double free or corruption with setAttributeNode())
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doc = new DOMDocument;
+$doc->loadXml(<<<EOF
+<?xml version="1.0" encoding="utf-8" ?>
+<aaa>
+ <bbb foo="bar"/>
+</aaa>
+EOF
+);
+
+$xpath = new DOMXPath($doc);
+
+$bbb = $xpath->query('bbb', $doc->documentElement)->item(0);
+
+$ccc = $doc->createElement('ccc');
+foreach ($bbb->attributes as $attr)
+{
+ $ccc->setAttributeNode($attr);
+}
+
+echo $attr->parentNode->localName;
+
+?>
+--EXPECT--
+ccc
diff --git a/ext/dom/tests/bug46185.phpt b/ext/dom/tests/bug46185.phpt
new file mode 100644
index 0000000..02117cd
--- /dev/null
+++ b/ext/dom/tests/bug46185.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #46185 (importNode changes the namespace of an XML element).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$aDOM = new DOMDocument();
+$aDOM->loadXML('<?xml version="1.0"?>
+<ns1:a xmlns:ns1="urn::ns"/>');
+$a= $aDOM->firstChild;
+
+$ok = new DOMDocument();
+$ok->loadXML('<?xml version="1.0"?>
+<ns1:ok xmlns:ns1="urn::ns" xmlns="urn::REAL"><watch-me xmlns:default="urn::BOGUS"/></ns1:ok>');
+
+$imported= $aDOM->importNode($ok->firstChild, true);
+$a->appendChild($imported);
+
+echo $aDOM->saveXML();
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<ns1:a xmlns:ns1="urn::ns"><ns1:ok xmlns="urn::REAL"><watch-me xmlns:default="urn::BOGUS"/></ns1:ok></ns1:a> \ No newline at end of file
diff --git a/ext/dom/tests/bug46335.phpt b/ext/dom/tests/bug46335.phpt
new file mode 100644
index 0000000..bea4ae9
--- /dev/null
+++ b/ext/dom/tests/bug46335.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #46335 (DOMText::splitText doesn't handle multibyte characters).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$textascii = 'This is an "example" of using DOM splitText';
+$text = 'This is an ‘example’ of using DOM splitText';
+$start = 30;
+$length = 3;
+
+$dom = new DOMDocument('1.0', 'UTF-8');
+$node = $dom->createTextNode($textascii);
+$dom->appendChild($node);
+
+print "Text: $node->textContent\n";
+
+$matched = $node->splitText($start);
+$matched->splitText($length);
+print "splitText (ASCII): $matched->textContent\n";
+
+$node = $dom->createTextNode($text);
+$dom->appendChild($node);
+
+print "Text: $node->textContent\n";
+
+$matched = $node->splitText($start);
+$matched->splitText($length);
+print "splitText (UTF-8): $matched->textContent\n";
+?>
+--EXPECT--
+Text: This is an "example" of using DOM splitText
+splitText (ASCII): DOM
+Text: This is an ‘example’ of using DOM splitText
+splitText (UTF-8): DOM
diff --git a/ext/dom/tests/bug46849.phpt b/ext/dom/tests/bug46849.phpt
new file mode 100644
index 0000000..c51c96e
--- /dev/null
+++ b/ext/dom/tests/bug46849.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #46849 (Cloning DOMDocument doesn't clone the properties).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new DOMDocument;
+$dom->formatOutput = 1;
+var_dump($dom->formatOutput);
+
+$dom2 = clone $dom;
+var_dump($dom2->formatOutput);
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/ext/dom/tests/bug47430.phpt b/ext/dom/tests/bug47430.phpt
new file mode 100644
index 0000000..243fe84
--- /dev/null
+++ b/ext/dom/tests/bug47430.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #47430 (Errors after writing to nodeValue parameter of an absent previousSibling).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = '<?xml
+version="1.0"?><html><p><i>Hello</i></p><p><i>World!</i></p></html>';
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+
+$elements = $dom->getElementsByTagName('i');
+foreach ($elements as $i) {
+ $i->previousSibling->nodeValue = '';
+}
+
+$arr = array();
+$arr[0] = 'Value';
+
+print_r($arr);
+
+?>
+--EXPECTF--
+Warning: Creating default object from empty value in %s on line %d
+
+Warning: Creating default object from empty value in %s on line %d
+Array
+(
+ [0] => Value
+)
diff --git a/ext/dom/tests/bug47848.phpt b/ext/dom/tests/bug47848.phpt
new file mode 100644
index 0000000..b4453c7
--- /dev/null
+++ b/ext/dom/tests/bug47848.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Bug #47848 (importNode doesn't preserve attribute namespaces)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$aDOM = new DOMDocument();
+$aDOM->appendChild($aDOM->createElementNS('http://friend2friend.net/','f2f:a'));
+
+$fromdom = new DOMDocument();
+$fromdom->loadXML('<data xmlns:ai="http://altruists.org" ai:attr="namespaced" />');
+
+$attr= $fromdom->firstChild->attributes->item(0);
+
+$att = $aDOM->importNode($attr);
+
+$aDOM->documentElement->appendChild($aDOM->importNode($attr, true));
+
+echo $aDOM->saveXML();
+
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<f2f:a xmlns:f2f="http://friend2friend.net/" xmlns:ai="http://altruists.org" ai:attr="namespaced"/> \ No newline at end of file
diff --git a/ext/dom/tests/bug47849.phpt b/ext/dom/tests/bug47849.phpt
new file mode 100644
index 0000000..7e6b02c
--- /dev/null
+++ b/ext/dom/tests/bug47849.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #47849 (Non-deep import loses the namespace).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$aDOM= new DOMDocument();
+$aDOM->appendChild($aDOM->createElementNS('urn::root','r:root'));
+
+$fromdom= new DOMDocument();
+$fromdom->loadXML('<data xmlns="urn::data">aaa</data>');
+
+$data= $fromdom->documentElement;
+$aDOM->documentElement->appendChild($aDOM->importNode($data));
+
+echo $aDOM->saveXML();
+
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<r:root xmlns:r="urn::root"><data xmlns="urn::data"/></r:root>
diff --git a/ext/dom/tests/bug49463.phpt b/ext/dom/tests/bug49463.phpt
new file mode 100644
index 0000000..4f232e3
--- /dev/null
+++ b/ext/dom/tests/bug49463.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #49463 (setAttributeNS fails setting default namespace).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument('1.0', 'utf-8');
+$root = $doc->createElementNS('http://purl.org/rss/1.0/','rdf:RDF');
+$doc->appendChild($root);
+$root->setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns","http://purl.org/rss/1.0/" );
+
+echo $doc->saveXML()."\n";
+?>
+--EXPECT--
+<?xml version="1.0" encoding="utf-8"?>
+<rdf:RDF xmlns:rdf="http://purl.org/rss/1.0/" xmlns="http://purl.org/rss/1.0/"/>
diff --git a/ext/dom/tests/bug49490.phpt b/ext/dom/tests/bug49490.phpt
new file mode 100644
index 0000000..897cfee
--- /dev/null
+++ b/ext/dom/tests/bug49490.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #49490 (XPath namespace prefix conflict).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$doc = new DOMDocument();
+$doc->loadXML('<prefix:root xmlns:prefix="urn:a" />');
+
+$xp = new DOMXPath($doc);
+$xp->registerNamespace('prefix', 'urn:b');
+
+echo($xp->query('//prefix:root', null, false)->length . "\n");
+
+?>
+--EXPECT--
+0
diff --git a/ext/dom/tests/bug50661.phpt b/ext/dom/tests/bug50661.phpt
new file mode 100644
index 0000000..3760db9
--- /dev/null
+++ b/ext/dom/tests/bug50661.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #50661 (DOMDocument::loadXML does not allow UTF-16).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$data = "\xFE\xFF\x00\x3C\x00\x66\x00\x6F\x00\x6F\x00\x2F\x00\x3E";
+
+$dom = new DOMDocument();
+$dom->loadXML($data);
+echo $dom->saveXML();
+
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<foo/>
diff --git a/ext/dom/tests/bug52656.phpt b/ext/dom/tests/bug52656.phpt
new file mode 100644
index 0000000..9ec2610
--- /dev/null
+++ b/ext/dom/tests/bug52656.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #52656 (DOMCdataSection does not work with splitText).
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$CData = new DOMCdataSection('splithere!');
+$CDataSplit = $CData->splitText(5);
+echo get_class($CDataSplit), "\n";
+var_dump($CDataSplit->data);
+?>
+--EXPECT--
+DOMText
+string(5) "here!"
diff --git a/ext/dom/tests/bug54601.phpt b/ext/dom/tests/bug54601.phpt
new file mode 100644
index 0000000..012302b
--- /dev/null
+++ b/ext/dom/tests/bug54601.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Segfault when removing the Doctype node
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<< XML
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE set PUBLIC "-//OASIS//DTD DocBook XML V5.0//EN" "http://www.docbook.org/xml/5.0/dtd/docbook.dtd" [
+<!ENTITY foo '<foo>footext</foo>'>
+<!ENTITY bar '<bar>bartext</bar>'>
+]>
+<set>&foo;&bar;</set>
+XML;
+
+$doc = new DOMDocument();
+$doc->loadXML($xml, LIBXML_NOENT);
+$n = $doc->doctype;
+$doc->removeChild($n);
+echo get_class($n), "\n";
+print $doc->saveXML();
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+DOMDocumentType
+<?xml version="1.0" encoding="utf-8"?>
+<set><foo>footext</foo><bar>bartext</bar></set>
+===DONE===
diff --git a/ext/dom/tests/canonicalization.phpt b/ext/dom/tests/canonicalization.phpt
new file mode 100644
index 0000000..cf1a81f
--- /dev/null
+++ b/ext/dom/tests/canonicalization.phpt
@@ -0,0 +1,102 @@
+--TEST--
+Test: Canonicalization - C14N()
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<<EOXML
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<foo xmlns="http://www.example.com/ns/foo"
+ xmlns:fubar="http://www.example.com/ns/fubar" xmlns:test="urn::test"><contain>
+ <bar><test1 /></bar>
+ <bar><test2 /></bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3 /></fubar:bar>
+ <fubar:bar><test4 /></fubar:bar>
+<!-- this is a comment -->
+</contain>
+</foo>
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$doc = $dom->documentElement->firstChild;
+
+/* inclusive/without comments first child element of doc element is context. */
+echo $doc->C14N()."\n\n";
+
+/* exclusive/without comments first child element of doc element is context. */
+echo $doc->c14N(TRUE)."\n\n";
+
+/* inclusive/with comments first child element of doc element is context. */
+echo $doc->C14N(FALSE, TRUE)."\n\n";
+
+/* exclusive/with comments first child element of doc element is context. */
+echo $doc->C14N(TRUE, TRUE)."\n\n";
+
+/* exclusive/without comments using xpath query. */
+echo $doc->c14N(TRUE, FALSE, array('query'=>'(//. | //@* | //namespace::*)'))."\n\n";
+
+/* exclusive/without comments first child element of doc element is context.
+ using xpath query with registered namespace.
+ test namespace prefix is also included. */
+echo $doc->c14N(TRUE, FALSE,
+ array('query'=>'(//a:contain | //a:bar | .//namespace::*)',
+ 'namespaces'=>array('a'=>'http://www.example.com/ns/foo')),
+ array('test'))."\n\n";
+
+/* exclusive/without comments first child element of doc element is context.
+ test namespace prefix is also included */
+echo $doc->C14N(TRUE, FALSE, NULL, array('test'));
+?>
+--EXPECTF--
+
+<contain xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:test="urn::test">
+ <bar><test1></test1></bar>
+ <bar><test2></test2></bar>
+ <fubar:bar><test3></test3></fubar:bar>
+ <fubar:bar><test4></test4></fubar:bar>
+
+</contain>
+
+<contain xmlns="http://www.example.com/ns/foo">
+ <bar><test1></test1></bar>
+ <bar><test2></test2></bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar>
+
+</contain>
+
+<contain xmlns="http://www.example.com/ns/foo" xmlns:fubar="http://www.example.com/ns/fubar" xmlns:test="urn::test">
+ <bar><test1></test1></bar>
+ <bar><test2></test2></bar>
+ <fubar:bar><test3></test3></fubar:bar>
+ <fubar:bar><test4></test4></fubar:bar>
+<!-- this is a comment -->
+</contain>
+
+<contain xmlns="http://www.example.com/ns/foo">
+ <bar><test1></test1></bar>
+ <bar><test2></test2></bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar>
+<!-- this is a comment -->
+</contain>
+
+<foo xmlns="http://www.example.com/ns/foo"><contain>
+ <bar><test1></test1></bar>
+ <bar><test2></test2></bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar>
+
+</contain>
+</foo>
+
+<contain xmlns="http://www.example.com/ns/foo" xmlns:test="urn::test"><bar></bar><bar></bar></contain>
+
+<contain xmlns="http://www.example.com/ns/foo" xmlns:test="urn::test">
+ <bar><test1></test1></bar>
+ <bar><test2></test2></bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test3></test3></fubar:bar>
+ <fubar:bar xmlns:fubar="http://www.example.com/ns/fubar"><test4></test4></fubar:bar>
+
+</contain>
diff --git a/ext/dom/tests/dom.ent b/ext/dom/tests/dom.ent
new file mode 100644
index 0000000..987ff9d
--- /dev/null
+++ b/ext/dom/tests/dom.ent
@@ -0,0 +1,8 @@
+<!ENTITY amp "&#38;#38;">
+<!ENTITY gt "&#62;">
+<!ENTITY % coreattrs "title CDATA #IMPLIED">
+<!ENTITY % attrs "%coreattrs;">
+<!ATTLIST foo bar CDATA #IMPLIED>
+<!ELEMENT foo (#PCDATA)>
+<!ELEMENT root (foo)+>
+<!ATTLIST th %attrs; > \ No newline at end of file
diff --git a/ext/dom/tests/dom.xml b/ext/dom/tests/dom.xml
new file mode 100644
index 0000000..09ac674
--- /dev/null
+++ b/ext/dom/tests/dom.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE root [
+<!ENTITY % incent SYSTEM "dom.ent">
+%incent;
+]>
+<root>
+ <foo bar="" />
+</root> \ No newline at end of file
diff --git a/ext/dom/tests/dom001.phpt b/ext/dom/tests/dom001.phpt
new file mode 100644
index 0000000..a0c78fb
--- /dev/null
+++ b/ext/dom/tests/dom001.phpt
@@ -0,0 +1,275 @@
+--TEST--
+Test 1: Accessing single node
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+echo "Test 1: accessing single nodes from php\n";
+$dom = new domDocument;
+$dom->loadxml($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+// children() of of document would result in a memleak
+//$children = $dom->children();
+//print_node_list($children);
+
+echo "--------- root\n";
+$rootnode = $dom->documentElement;
+print_node($rootnode);
+
+echo "--------- children of root\n";
+$children = $rootnode->childNodes;
+print_node_list($children);
+
+// The last node should be identical with the last entry in the children array
+echo "--------- last\n";
+$last = $rootnode->lastChild;
+print_node($last);
+
+// The parent of this last node is the root again
+echo "--------- parent\n";
+$parent = $last->parentNode;
+print_node($parent);
+
+// The children of this parent are the same children as one above
+echo "--------- children of parent\n";
+$children = $parent->childNodes;
+print_node_list($children);
+
+echo "--------- creating a new attribute\n";
+//This is worthless
+//$attr = $dom->createAttribute("src", "picture.gif");
+//print_r($attr);
+
+//$rootnode->set_attributeNode($attr);
+$attr = $rootnode->setAttribute("src", "picture.gif");
+$attr = $rootnode->getAttribute("src");
+print_r($attr);
+print "\n";
+
+echo "--------- Get Attribute Node\n";
+$attr = $rootnode->getAttributeNode("src");
+print_node($attr);
+
+echo "--------- Remove Attribute Node\n";
+$attr = $rootnode->removeAttribute("src");
+print "Removed " . $attr . " attributes.\n";
+
+echo "--------- attributes of rootnode\n";
+$attrs = $rootnode->attributes;
+print_node_list($attrs);
+
+echo "--------- children of an attribute\n";
+$children = $attrs->item(0)->childNodes;
+print_node_list($children);
+
+echo "--------- Add child to root\n";
+$myelement = new domElement("Silly", "Symphony");
+$newchild = $rootnode->appendChild($myelement);
+print_node($newchild);
+print $dom->saveXML();
+print "\n";
+
+echo "--------- Find element by tagname\n";
+echo " Using dom\n";
+$children = $dom->getElementsByTagname("Silly");
+print_node_list($children);
+
+echo " Using elem\n";
+$children = $rootnode->getElementsByTagName("Silly");
+print_node_list($children);
+
+echo "--------- Unlink Node\n";
+print_node($children->item(0));
+$rootnode->removeChild($children->item(0));
+print_node_list($rootnode->childNodes);
+print $dom->savexml();
+
+echo "--------- Find element by id\n";
+print ("Not implemented\n");
+
+echo "--------- Check various node_name return values\n";
+print ("Not needed\n");
+
+?>
+--EXPECT--
+Test 1: accessing single nodes from php
+--------- root
+Node Name: chapter
+Node Type: 1
+Num Children: 4
+
+--------- children of root
+Node Name: title
+Node Type: 1
+Num Children: 1
+Node Content: Title
+
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+Node Name: para
+Node Type: 1
+Num Children: 7
+
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+--------- last
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+--------- parent
+Node Name: chapter
+Node Type: 1
+Num Children: 4
+
+--------- children of parent
+Node Name: title
+Node Type: 1
+Num Children: 1
+Node Content: Title
+
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+Node Name: para
+Node Type: 1
+Num Children: 7
+
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+--------- creating a new attribute
+picture.gif
+--------- Get Attribute Node
+Node Name: src
+Node Type: 2
+Num Children: 1
+Node Content: picture.gif
+
+--------- Remove Attribute Node
+Removed 1 attributes.
+--------- attributes of rootnode
+Node Name: language
+Node Type: 2
+Num Children: 1
+Node Content: en
+
+--------- children of an attribute
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content: en
+
+--------- Add child to root
+Node Name: Silly
+Node Type: 1
+Num Children: 1
+Node Content: Symphony
+
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE chapter SYSTEM "/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd" [
+<!ENTITY sp "spanish">
+]>
+<!-- lsfj -->
+<chapter language="en"><title language="en">Title</title>
+<para language="ge">
+&sp;
+<!-- comment -->
+<informaltable language="&sp;kkk">
+<tgroup cols="3">
+<tbody>
+<row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
+<row><entry>a2</entry><entry>c2</entry></row>
+<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+<Silly>Symphony</Silly></chapter>
+
+--------- Find element by tagname
+ Using dom
+Node Name: Silly
+Node Type: 1
+Num Children: 1
+Node Content: Symphony
+
+ Using elem
+Node Name: Silly
+Node Type: 1
+Num Children: 1
+Node Content: Symphony
+
+--------- Unlink Node
+Node Name: Silly
+Node Type: 1
+Num Children: 1
+Node Content: Symphony
+
+Node Name: title
+Node Type: 1
+Num Children: 1
+Node Content: Title
+
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+Node Name: para
+Node Type: 1
+Num Children: 7
+
+Node Name: #text
+Node Type: 3
+Num Children: 0
+Node Content:
+
+
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE chapter SYSTEM "/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd" [
+<!ENTITY sp "spanish">
+]>
+<!-- lsfj -->
+<chapter language="en"><title language="en">Title</title>
+<para language="ge">
+&sp;
+<!-- comment -->
+<informaltable language="&sp;kkk">
+<tgroup cols="3">
+<tbody>
+<row><entry>a1</entry><entry morerows="1">b1</entry><entry>c1</entry></row>
+<row><entry>a2</entry><entry>c2</entry></row>
+<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+</chapter>
+--------- Find element by id
+Not implemented
+--------- Check various node_name return values
+Not needed
diff --git a/ext/dom/tests/dom002.phpt b/ext/dom/tests/dom002.phpt
new file mode 100644
index 0000000..3343a17
--- /dev/null
+++ b/ext/dom/tests/dom002.phpt
@@ -0,0 +1,57 @@
+--TEST--
+Test 2: getElementsByTagName() / getElementsByTagNameNS()
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<<HERE
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<foo xmlns="http://www.example.com/ns/foo"
+ xmlns:fubar="http://www.example.com/ns/fubar">
+ <bar><test1 /></bar>
+ <bar><test2 /></bar>
+ <fubar:bar><test3 /></fubar:bar>
+ <fubar:bar><test4 /></fubar:bar>
+</foo>
+HERE;
+
+function dump($elems) {
+ foreach ($elems as $elem) {
+ var_dump($elem->nodeName);
+ dump($elem->childNodes);
+ }
+}
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$doc = $dom->documentElement;
+dump($dom->getElementsByTagName('bar'));
+dump($doc->getElementsByTagName('bar'));
+dump($dom->getElementsByTagNameNS('http://www.example.com/ns/fubar', 'bar'));
+dump($doc->getElementsByTagNameNS('http://www.example.com/ns/fubar', 'bar'));
+?>
+--EXPECT--
+string(3) "bar"
+string(5) "test1"
+string(3) "bar"
+string(5) "test2"
+string(9) "fubar:bar"
+string(5) "test3"
+string(9) "fubar:bar"
+string(5) "test4"
+string(3) "bar"
+string(5) "test1"
+string(3) "bar"
+string(5) "test2"
+string(9) "fubar:bar"
+string(5) "test3"
+string(9) "fubar:bar"
+string(5) "test4"
+string(9) "fubar:bar"
+string(5) "test3"
+string(9) "fubar:bar"
+string(5) "test4"
+string(9) "fubar:bar"
+string(5) "test3"
+string(9) "fubar:bar"
+string(5) "test4"
diff --git a/ext/dom/tests/dom003.phpt b/ext/dom/tests/dom003.phpt
new file mode 100644
index 0000000..060a2c1
--- /dev/null
+++ b/ext/dom/tests/dom003.phpt
@@ -0,0 +1,69 @@
+--TEST--
+Test 3: Exception Test
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$dom = new domdocument;
+$dom->load(dirname(__FILE__)."/book.xml");
+$rootNode = $dom->documentElement;
+print "--- Catch exception with try/catch\n";
+try {
+ $rootNode->appendChild($rootNode);
+} catch (domexception $e) {
+ ob_start();
+ var_dump($e);
+ $contents = ob_get_contents();
+ ob_end_clean();
+ echo preg_replace('/object\(DOMElement\).+\{.*?\}/s', 'DOMElement', $contents);
+}
+print "--- Don't catch exception with try/catch\n";
+$rootNode->appendChild($rootNode);
+
+
+?>
+--EXPECTF--
+--- Catch exception with try/catch
+object(DOMException)#%d (%d) {
+ ["message":protected]=>
+ string(23) "Hierarchy Request Error"
+ ["string":"Exception":private]=>
+ string(0) ""
+ ["file":protected]=>
+ string(%d) "%sdom003.php"
+ ["line":protected]=>
+ int(8)
+ ["trace":"Exception":private]=>
+ array(1) {
+ [0]=>
+ array(6) {
+ ["file"]=>
+ string(%d) "%sdom003.php"
+ ["line"]=>
+ int(8)
+ ["function"]=>
+ string(11) "appendChild"
+ ["class"]=>
+ string(7) "DOMNode"
+ ["type"]=>
+ string(2) "->"
+ ["args"]=>
+ array(1) {
+ [0]=>
+ DOMElement
+ }
+ }
+ }
+ ["previous":"Exception":private]=>
+ NULL
+ ["code"]=>
+ int(3)
+}
+--- Don't catch exception with try/catch
+
+Fatal error: Uncaught exception 'DOMException' with message 'Hierarchy Request Error' in %sdom003.php:%d
+Stack trace:
+#0 %sdom003.php(%d): DOMNode->appendChild(Object(DOMElement))
+#1 {main}
+ thrown in %sdom003.php on line %d
diff --git a/ext/dom/tests/dom004.phpt b/ext/dom/tests/dom004.phpt
new file mode 100644
index 0000000..5b65f24
--- /dev/null
+++ b/ext/dom/tests/dom004.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Test 4: Streams Test
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+in_array('compress.zlib', stream_get_wrappers()) or die('skip compress.zlib wrapper is not available');
+?>
+--FILE--
+<?php
+$dom = new domdocument;
+$dom->load("compress.zlib://".dirname(__FILE__)."/book.xml.gz");
+print $dom->saveXML();
+
+--EXPECT--
+<?xml version="1.0"?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/dom005.phpt b/ext/dom/tests/dom005.phpt
new file mode 100644
index 0000000..715aec4
--- /dev/null
+++ b/ext/dom/tests/dom005.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Test 5: HTML Test
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dom = new domdocument;
+$dom->loadHTMLFile(dirname(__FILE__)."/test.html");
+print "--- save as XML\n";
+
+print adjustDoctype($dom->saveXML());
+print "--- save as HTML\n";
+
+print adjustDoctype($dom->saveHTML());
+
+function adjustDoctype($xml) {
+ return str_replace(array("DOCTYPE HTML",'<p>','</p>'),array("DOCTYPE html",'',''),$xml);
+}
+
+--EXPECT--
+--- save as XML
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html><head><title>Hello world</title></head><body>
+This is a not well-formed<br/>
+html files with undeclared entities&#xA0;
+</body></html>
+--- save as HTML
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html><head><title>Hello world</title></head><body>
+This is a not well-formed<br>
+html files with undeclared entities&nbsp;
+</body></html>
diff --git a/ext/dom/tests/dom006.phpt b/ext/dom/tests/dom006.phpt
new file mode 100644
index 0000000..b8e8ed1
--- /dev/null
+++ b/ext/dom/tests/dom006.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Test 6: Extends Test
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+Class books extends domDocument {
+ function addBook($title, $author) {
+ $titleElement = $this->createElement("title");
+ $titleElement->appendChild($this->createTextNode($title));
+ $authorElement = $this->createElement("author");
+ $authorElement->appendChild($this->createTextNode($author));
+
+ $bookElement = $this->createElement("book");
+
+ $bookElement->appendChild($titleElement);
+ $bookElement->appendChild($authorElement);
+ $this->documentElement->appendChild($bookElement);
+ }
+
+}
+
+$dom = new books;
+
+$dom->load(dirname(__FILE__)."/book.xml");
+$dom->addBook("PHP de Luxe", "Richard Samar, Christian Stocker");
+print $dom->saveXML();
+--EXPECT--
+<?xml version="1.0"?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+<book><title>PHP de Luxe</title><author>Richard Samar, Christian Stocker</author></book></books>
diff --git a/ext/dom/tests/dom007.phpt b/ext/dom/tests/dom007.phpt
new file mode 100644
index 0000000..5d12aa3
--- /dev/null
+++ b/ext/dom/tests/dom007.phpt
@@ -0,0 +1,111 @@
+--TEST--
+Test 7: DTD tests
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+$xml = <<< EOXML
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE courses [
+<!ELEMENT courses (course+)>
+<!ELEMENT course (title, description, temp*)>
+<!ATTLIST course cid ID #REQUIRED>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT description (#PCDATA)>
+<!ELEMENT temp (#PCDATA)>
+<!ATTLIST temp vid ID #REQUIRED>
+<!ENTITY test 'http://www.hpl.hp.com/semweb/2003/query_tester#'>
+<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
+<!NOTATION GIF PUBLIC "-" "image/gif">
+<!ENTITY myimage PUBLIC "-" "mypicture.gif" NDATA GIF>
+]>
+<courses>
+ <course cid="c1">
+ <title>Basic Languages</title>
+ <description>Introduction to Languages</description>
+ </course>
+ <course cid="c6">
+ <title>French I</title>
+ <description>Introduction to French</description>
+ <temp vid="c7">
+ </temp>
+ </course>
+</courses>
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+
+$dtd = $dom->doctype;
+
+/* Notation Tests */
+$nots = $dtd->notations;
+
+$length = $nots->length;
+echo "Length: ".$length."\n";
+
+foreach ($nots AS $key=>$node) {
+ echo "Key $key: ".$node->nodeName." (".$node->systemId.") (".$node->publicId.")\n";
+}
+print "\n";
+for($x=0; $x < $length; $x++) {
+ echo "Index $x: ".$nots->item($x)->nodeName." (".$nots->item($x)->systemId.") (".$nots->item($x)->publicId.")\n";
+}
+
+echo "\n";
+$node = $nots->getNamedItem('xxx');
+var_dump($node);
+
+echo "\n";
+/* Entity Decl Tests */
+$ents = $dtd->entities;
+$length = $ents->length;
+echo "Length: ".$length."\n";
+
+$xkeys = array();
+foreach ($ents AS $key=>$node) {
+ $xkeys[] = "Key: $key Name: ".$node->nodeName."\n";
+}
+sort($xkeys); // fix inconsistent output ordering (bug #61810)
+foreach ($xkeys as $key => $node) {
+ echo $node;
+}
+echo "\n";
+
+$xkeys = array();
+for($x=0; $x < $length; $x++) {
+ $xkeys[] = "Index: ".$ents->item($x)->nodeName."\n";
+}
+sort($xkeys); // fix inconsistent output ordering (bug #61810)
+foreach ($xkeys as $key => $node) {
+ echo $node;
+}
+
+echo "\n";
+$node = $ents->item(3);
+var_dump($node);
+$node = $ents->getNamedItem('xxx');
+var_dump($node);
+
+
+--EXPECT--
+Length: 1
+Key GIF: GIF (image/gif) (-)
+
+Index 0: GIF (image/gif) (-)
+
+NULL
+
+Length: 3
+Key: myimage Name: myimage
+Key: rdf Name: rdf
+Key: test Name: test
+
+Index: myimage
+Index: rdf
+Index: test
+
+NULL
+NULL
diff --git a/ext/dom/tests/dom_comment_basic.phpt b/ext/dom/tests/dom_comment_basic.phpt
new file mode 100644
index 0000000..3a69705
--- /dev/null
+++ b/ext/dom/tests/dom_comment_basic.phpt
@@ -0,0 +1,43 @@
+--TEST--
+DOM Comment : Basic Functionality
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+
+$xml = <<< EOXML
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<courses>
+ <!-- Hello World! -->
+</courses>
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$root = $dom->documentElement;
+var_dump($root->hasChildNodes());
+$children = $root->childNodes;
+
+for ($index = 0; $index < $children->length; $index++) {
+ echo "--- child $index ---\n";
+ $current = $children->item($index);
+ echo get_class($current), "\n";
+ var_dump($current->textContent);
+}
+
+--EXPECTF--
+bool(true)
+--- child 0 ---
+DOMText
+string(2) "
+ "
+--- child 1 ---
+DOMComment
+string(14) " Hello World! "
+--- child 2 ---
+DOMText
+string(1) "
+"
+
diff --git a/ext/dom/tests/dom_comment_variation.phpt b/ext/dom/tests/dom_comment_variation.phpt
new file mode 100644
index 0000000..1f30e7c
--- /dev/null
+++ b/ext/dom/tests/dom_comment_variation.phpt
@@ -0,0 +1,32 @@
+--TEST--
+DOM Comment : Variation
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+
+$xml = <<< EOXML
+<?xml version="1.0" encoding="ISO-8859-1"?><courses><!-- Hello World! --></courses>
+EOXML;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$root = $dom->documentElement;
+var_dump($root->hasChildNodes());
+$children = $root->childNodes;
+
+for ($index = 0; $index < $children->length; $index++) {
+ echo "--- child $index ---\n";
+ $current = $children->item($index);
+ echo get_class($current), "\n";
+ var_dump($current->textContent);
+}
+
+--EXPECTF--
+bool(true)
+--- child 0 ---
+DOMComment
+string(14) " Hello World! "
+
diff --git a/ext/dom/tests/dom_create_element.phpt b/ext/dom/tests/dom_create_element.phpt
new file mode 100644
index 0000000..3f30709
--- /dev/null
+++ b/ext/dom/tests/dom_create_element.phpt
@@ -0,0 +1,394 @@
+--TEST--
+Test 1: Creating Elements with and without Namespaces
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+print " 1 DOMDocument::createElement('valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElement('valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 2 DOMDocument::createElement('-invalid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElement('-invalid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 3 DOMDocument::createElement(' ')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElement(' ');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 4 DOMDocument::createElement('prefix:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElement('prefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 5 DOMDocument::createElementNS('http://valid.com', 'valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://valid.com', 'valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 6 DOMDocument::createElementNS('http://valid.com', 'prefix:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://valid.com', 'prefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 7 DOMDocument::createElementNS('http://valid.com', '-invalid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://valid.com', '-invalid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 8 DOMDocument::createElementNS('http://valid.com', 'prefix:-invalid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://valid.com', 'prefix:-invalid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print " 9 DOMDocument::createElementNS('', 'prefix:invalid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('', 'prefix:invalid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "10 DOMDocument::createElementNS('http://valid.com', 'prefix:valid:invalid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://valid.com', 'prefix:valid:invalid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "11 DOMDocument::createElementNS('http://valid.com', '-prefix:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://valid.com', '-prefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "12 DOMDocument::createElementNS('-', 'prefix:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('-', 'prefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+
+print "13 DOMElement::__construct('valid')\n";
+try {
+ $element = new DomElement('valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "14 DOMElement::__construct('-invalid')\n";
+try {
+ $element = new DomElement('-invalid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "15 DOMElement::__construct(' ')\n";
+try {
+ $element = new DomElement(' ');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "16 DOMElement::__construct('prefix:valid')\n";
+try {
+ $element = new DomElement('prefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "17 DOMElement::__construct('valid', '', 'http://valid.com')\n";
+try {
+ $element = new DomElement('valid', '', 'http://valid.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "18 DOMElement::__construct('prefix:valid', '', 'http://valid.com')\n";
+try {
+ $element = new DomElement('prefix:valid', '', 'http://valid.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "19 DOMElement::__construct('-invalid', '', 'http://valid.com')\n";
+try {
+ $element = new DomElement('-invalid', '', 'http://valid.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "20 DOMElement::__construct('prefix:-invalid', '', 'http://valid.com')\n";
+try {
+ $element = new DomElement('prefix:-invalid', '', 'http://valid.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "21 DOMElement::__construct('prefix:invalid', '', '')\n";
+try {
+ $element = new DomElement('prefix:invalid', '', '');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "22 DOMElement::__construct('prefix:valid:invalid', '', 'http://valid.com')\n";
+try {
+ $element = new DomElement('prefix:valid:invalid', '', 'http://valid.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "23 DOMElement::__construct('-prefix:valid', '', 'http://valid.com')\n";
+try {
+ $element = new DomElement('-prefix:valid', '', 'http://valid.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "24 DOMElement::__construct('prefix:valid', '', '-')\n";
+try {
+ $element = new DomElement('prefix:valid', '', '-');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+/* the qualifiedName has a prefix and the namespaceURI is null */
+
+print "25 DOMDocument::createElementNS('', 'prefix:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('', 'prefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+/* the qualifiedName has a prefix that is "xml" and the namespaceURI
+ is different from "http://www.w3.org/XML/1998/namespace" [XML Namespaces] */
+
+print "26 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xml:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://wrong.namespaceURI.com', 'xml:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "27 DOMElement::__construct('xml:valid', '', 'http://wrong.namespaceURI.com')\n";
+try {
+ $element = new DomElement('xml:valid', '', 'http://wrong.namespaceURI.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+/* This is okay because we reuse the xml namespace from the document */
+print "28 DOMDocument::createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+/* This isn't because the xml namespace isn't there and we can't create it */
+print "29 DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace')\n";
+try {
+ $element = new DomElement('xml:valid', '', 'http://www.w3.org/XML/1998/namespace');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+
+/* the qualifiedName or its prefix is "xmlns" and the namespaceURI is
+ different from "http://www.w3.org/2000/xmlns/" */
+
+print "30 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "31 DOMElement::__construct('xmlns:valid', '', 'http://wrong.namespaceURI.com')\n";
+try {
+ $element = new DomElement('xmlns:valid', '', 'http://wrong.namespaceURI.com');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "32 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'xmlns:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://www.w3.org/2000/xmlns/', 'xmlns:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "33 DOMElement::__construct('xmlns:valid', '', 'http://www.w3.org/2000/xmlns/')\n";
+try {
+ $element = new DomElement('xmlns:valid', '', 'http://www.w3.org/2000/xmlns/');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+/* the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the
+ qualifiedName nor its prefix is "xmlns". */
+
+print "34 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'wrongprefix:valid')\n";
+try {
+ $dom = new domDocument;
+ $dom->createElementNS('http://www.w3.org/2000/xmlns/', 'wrongprefix:valid');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+print "35 DOMElement::__construct('wrongprefix:valid', '', 'http://www.w3.org/2000/xmlns/')\n";
+try {
+ $element = new DomElement('wrongprefix:valid', '', 'http://www.w3.org/2000/xmlns/');
+ print "valid\n";
+} catch (Exception $e) {
+ print $e->getMessage() . "\n";
+}
+
+
+
+?>
+--EXPECT--
+ 1 DOMDocument::createElement('valid')
+valid
+ 2 DOMDocument::createElement('-invalid')
+Invalid Character Error
+ 3 DOMDocument::createElement(' ')
+Invalid Character Error
+ 4 DOMDocument::createElement('prefix:valid')
+valid
+ 5 DOMDocument::createElementNS('http://valid.com', 'valid')
+valid
+ 6 DOMDocument::createElementNS('http://valid.com', 'prefix:valid')
+valid
+ 7 DOMDocument::createElementNS('http://valid.com', '-invalid')
+Namespace Error
+ 8 DOMDocument::createElementNS('http://valid.com', 'prefix:-invalid')
+Namespace Error
+ 9 DOMDocument::createElementNS('', 'prefix:invalid')
+Namespace Error
+10 DOMDocument::createElementNS('http://valid.com', 'prefix:valid:invalid')
+Namespace Error
+11 DOMDocument::createElementNS('http://valid.com', '-prefix:valid')
+Namespace Error
+12 DOMDocument::createElementNS('-', 'prefix:valid')
+valid
+13 DOMElement::__construct('valid')
+valid
+14 DOMElement::__construct('-invalid')
+Invalid Character Error
+15 DOMElement::__construct(' ')
+Invalid Character Error
+16 DOMElement::__construct('prefix:valid')
+Namespace Error
+17 DOMElement::__construct('valid', '', 'http://valid.com')
+valid
+18 DOMElement::__construct('prefix:valid', '', 'http://valid.com')
+valid
+19 DOMElement::__construct('-invalid', '', 'http://valid.com')
+Invalid Character Error
+20 DOMElement::__construct('prefix:-invalid', '', 'http://valid.com')
+Namespace Error
+21 DOMElement::__construct('prefix:invalid', '', '')
+Namespace Error
+22 DOMElement::__construct('prefix:valid:invalid', '', 'http://valid.com')
+Namespace Error
+23 DOMElement::__construct('-prefix:valid', '', 'http://valid.com')
+Invalid Character Error
+24 DOMElement::__construct('prefix:valid', '', '-')
+valid
+25 DOMDocument::createElementNS('', 'prefix:valid')
+Namespace Error
+26 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xml:valid')
+Namespace Error
+27 DOMElement::__construct('xml:valid', '', 'http://wrong.namespaceURI.com')
+Namespace Error
+28 DOMDocument::createElementNS('http://www.w3.org/XML/1998/namespace', 'xml:valid')
+valid
+29 DOMElement::__construct('xml:valid', '', 'http://www.w3.org/XML/1998/namespace')
+Namespace Error
+30 DOMDocument::createElementNS('http://wrong.namespaceURI.com', 'xmlns:valid')
+Namespace Error
+31 DOMElement::__construct('xmlns:valid', '', 'http://wrong.namespaceURI.com')
+Namespace Error
+32 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'xmlns:valid')
+valid
+33 DOMElement::__construct('xmlns:valid', '', 'http://www.w3.org/2000/xmlns/')
+valid
+34 DOMDocument::createElementNS('http://www.w3.org/2000/xmlns/', 'wrongprefix:valid')
+Namespace Error
+35 DOMElement::__construct('wrongprefix:valid', '', 'http://www.w3.org/2000/xmlns/')
+Namespace Error
diff --git a/ext/dom/tests/dom_import_simplexml.phpt b/ext/dom/tests/dom_import_simplexml.phpt
new file mode 100644
index 0000000..81744aa
--- /dev/null
+++ b/ext/dom/tests/dom_import_simplexml.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Interop Test: Import from SimpleXML
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (!extension_loaded('simplexml')) die('skip simplexml extension not available');?>
+--FILE--
+<?php
+$s = simplexml_load_file(dirname(__FILE__)."/book.xml");
+if(!$s) {
+ echo "Error while loading the document\n";
+ exit;
+}
+$dom = dom_import_simplexml($s);
+print $dom->ownerDocument->saveXML();
+?>
+--EXPECT--
+<?xml version="1.0"?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/dom_set_attr_node.phpt b/ext/dom/tests/dom_set_attr_node.phpt
new file mode 100644
index 0000000..1916cd5
--- /dev/null
+++ b/ext/dom/tests/dom_set_attr_node.phpt
@@ -0,0 +1,74 @@
+--TEST--
+Test: setAttributeNode()
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+error_reporting = E_ALL & ~E_WARNING
+--FILE--
+<?php
+
+$xml = <<<HERE
+<?xml version="1.0" ?>
+<root a="b" />
+HERE;
+
+$xml2 = <<<HERE
+<?xml version="1.0" ?>
+<doc2 />
+HERE;
+
+$dom = new DOMDocument();
+$dom->loadXML($xml);
+$root = $dom->documentElement;
+$attr = $root->getAttributeNode('a');
+
+$dom2 = new DOMDocument();
+$dom2->loadXML($xml2);
+$root2 = $dom2->documentElement;
+try {
+ $root2->setAttributeNode($attr);
+} catch (domexception $e) {
+ob_start();
+ var_dump($e);
+ $contents = ob_get_contents();
+ ob_end_clean();
+ echo preg_replace('/object\(DOMAttr\).+\{.*?\}/s', 'DOMAttr', $contents);
+}
+
+?>
+--EXPECTF--
+object(DOMException)#%d (7) {
+ ["message":protected]=>
+ string(20) "Wrong Document Error"
+ ["string":"Exception":private]=>
+ string(0) ""
+ ["file":protected]=>
+ string(%d) "%sdom_set_attr_node.php"
+ ["line":protected]=>
+ int(%d)
+ ["trace":"Exception":private]=>
+ array(1) {
+ [0]=>
+ array(6) {
+ ["file"]=>
+ string(%d) "%sdom_set_attr_node.php"
+ ["line"]=>
+ int(%d)
+ ["function"]=>
+ string(16) "setAttributeNode"
+ ["class"]=>
+ string(10) "DOMElement"
+ ["type"]=>
+ string(2) "->"
+ ["args"]=>
+ array(1) {
+ [0]=>
+ DOMAttr
+ }
+ }
+ }
+ ["previous":"Exception":private]=>
+ NULL
+ ["code"]=>
+ int(4)
+}
diff --git a/ext/dom/tests/dom_test.inc b/ext/dom/tests/dom_test.inc
new file mode 100644
index 0000000..86b426f
--- /dev/null
+++ b/ext/dom/tests/dom_test.inc
@@ -0,0 +1,47 @@
+<?PHP
+$xmlstr = "<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE chapter SYSTEM '/share/sgml/Norman_Walsh/db3xml10/db3xml10.dtd'
+[ <!ENTITY sp \"spanish\">
+]>
+<!-- lsfj -->
+<chapter language='en'><title language='en'>Title</title>
+<para language='ge'>
+&sp;
+<!-- comment -->
+<informaltable language='&sp;kkk'>
+<tgroup cols='3'>
+<tbody>
+<row><entry>a1</entry><entry morerows='1'>b1</entry><entry>c1</entry></row>
+<row><entry>a2</entry><entry>c2</entry></row>
+<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
+</tbody>
+</tgroup>
+</informaltable>
+</para>
+</chapter> ";
+
+function print_node($node)
+{
+ print "Node Name: " . $node->nodeName;
+ print "\nNode Type: " . $node->nodeType;
+ if ($node->nodeType != 3) {
+ $child_count = $node->childNodes->length;
+ } else {
+ $child_count = 0;
+ }
+ print "\nNum Children: " . $child_count;
+ if($child_count <= 1){
+ print "\nNode Content: " . $node->nodeValue;
+ }
+ print "\n\n";
+}
+
+function print_node_list($nodelist)
+{
+ foreach($nodelist as $node)
+ {
+ print_node($node);
+ }
+}
+
+?>
diff --git a/ext/dom/tests/dom_xinclude.phpt b/ext/dom/tests/dom_xinclude.phpt
new file mode 100644
index 0000000..5d8906e
--- /dev/null
+++ b/ext/dom/tests/dom_xinclude.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Test: Xinclude and Streams
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+in_array('compress.zlib', stream_get_wrappers()) or die('skip compress.zlib wrapper is not available');
+?>
+--FILE--
+<?php
+$dom = new domdocument;
+
+$data = file_get_contents(dirname(__FILE__)."/xinclude.xml");
+$reldir = str_replace(getcwd(),".",dirname(__FILE__));
+if (DIRECTORY_SEPARATOR == '\\') {
+ $reldir = str_replace('\\',"/", $reldir);
+}
+$data = str_replace('compress.zlib://ext/dom/tests/','compress.zlib://'.$reldir."/", $data);
+
+
+$dom->loadXML($data);
+$dom->xinclude();
+print $dom->saveXML()."\n";
+foreach ($dom->documentElement->childNodes as $node) {
+ print $node->nodeName."\n";
+}
+?>
+--EXPECTF--
+<?xml version="1.0"?>
+<foo xmlns:xi="http://www.w3.org/2001/XInclude">
+ <book xml:base="compress.zlib://%sbook.xml">
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book><book xml:base="compress.zlib://%sbook.xml">
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+ </foo>
+
+#text
+book
+book
+#text
diff --git a/ext/dom/tests/domattributes.phpt b/ext/dom/tests/domattributes.phpt
new file mode 100644
index 0000000..9097a88
--- /dev/null
+++ b/ext/dom/tests/domattributes.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Attributes: DOMAttribute functionality
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$node = $dom->documentElement;
+
+$lang = $node->getAttributeNode('language');
+echo "Language: ".$lang->value."\n";
+
+$lang->value = 'en-US';
+echo "Language: ".$lang->value."\n";
+
+$parent = $lang->ownerElement;
+
+$chapter = new DOMAttr("num", "1");
+$parent->setAttributeNode($chapter);
+
+echo "Is ID?: ".($chapter->isId()?'YES':'NO')."\n";
+
+$top_element = $node->cloneNode();
+
+print $dom->saveXML($top_element);
+
+
+?>
+--EXPECT--
+
+Language: en
+Language: en-US
+Is ID?: NO
+<chapter language="en-US" num="1"/>
+
diff --git a/ext/dom/tests/domchardata.phpt b/ext/dom/tests/domchardata.phpt
new file mode 100644
index 0000000..6baff6d
--- /dev/null
+++ b/ext/dom/tests/domchardata.phpt
@@ -0,0 +1,76 @@
+--TEST--
+CharData: DOMCharacterData and related functionality
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$node = $dom->documentElement;
+
+$charnode = $dom->createElement('charnode');
+$node->appendChild($charnode);
+
+/* DOMComment */
+$comment = new DOMComment('Testing character data and extending nodes');
+$charnode->appendChild($comment);
+
+echo "Comment Length: ".$comment->length."\n";
+
+$comment->data = 'Updated comment';
+echo "New Comment Length: ".$comment->length."\n";
+echo "New Comment Data: ".$comment->data."\n";
+
+/* DOMCDataSection */
+$cdata = new DOMCDataSection('Chars: <>&"');
+$charnode->appendChild($cdata);
+
+echo "Substring: ".$cdata->substringData(7, 4)."\n";
+$cdata->replaceData(10, 1, "'");
+echo "New Substring: ".$cdata->substringData(7, 4)."\n";
+
+/* DOMCharacterData using DOMComment */
+$comment = new DOMComment('instructions');
+echo "Comment Value: ".$comment->data."\n";
+$comment->data = 'some more instructions';
+echo "New Comment Value: ".$comment->data."\n";
+
+$comment->insertData(10, 'pi ');
+$comment->replaceData(18, 5, 'i');
+$comment->insertData(20, 'g');
+$comment->deleteData(13, 2);
+$comment->deleteData(10, 3);
+$comment->insertData(10, 'comment ');
+echo "Updated Comment Value: ".$comment->data."\n";
+
+/* DOMText */
+$text = new DOMText('some text characters');
+
+echo "Whole Text: ".$text->wholeText."\n";
+$text2 = $text->splitText(9);
+
+echo "Split text: ".$text2->wholeText."\n";
+$text3 = $text2->splitText(1);
+
+echo "Is Whitespace?: ".($text2->isElementContentWhitespace()?'YES':'NO');
+?>
+--EXPECT--
+
+Comment Length: 42
+New Comment Length: 15
+New Comment Data: Updated comment
+Substring: <>&"
+New Substring: <>&'
+Comment Value: instructions
+New Comment Value: some more instructions
+Updated Comment Value: some more comment strings
+Whole Text: some text characters
+Split text: characters
+Is Whitespace?: YES
diff --git a/ext/dom/tests/domdocument_createcomment_error_001.phpt b/ext/dom/tests/domdocument_createcomment_error_001.phpt
new file mode 100644
index 0000000..24104a1
--- /dev/null
+++ b/ext/dom/tests/domdocument_createcomment_error_001.phpt
@@ -0,0 +1,16 @@
+--TEST--
+DomDocument::CreateComment() - Incorrect Parameters
+--CREDITS--
+Clint Priest @ PhpTek09
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ $x = new DomDocument();
+ $x->createComment();
+?>
+===DONE===
+--EXPECTF--
+Warning: DOMDocument::createComment() expects exactly 1 parameter, 0 given in %s
+===DONE===
+ \ No newline at end of file
diff --git a/ext/dom/tests/domdocument_createentityreference_001.phpt b/ext/dom/tests/domdocument_createentityreference_001.phpt
new file mode 100644
index 0000000..7343e74
--- /dev/null
+++ b/ext/dom/tests/domdocument_createentityreference_001.phpt
@@ -0,0 +1,18 @@
+--TEST--
+DomDocument::CreateEntityReference() - Creates an entity reference with the appropriate name
+--CREDITS--
+Clint Priest @ PhpTek09
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ $objDoc = new DomDocument();
+
+ $objRef = $objDoc->createEntityReference('Test');
+ echo $objRef->nodeName . "\n";
+?>
+===DONE===
+--EXPECT--
+Test
+===DONE===
+ \ No newline at end of file
diff --git a/ext/dom/tests/domdocument_createentityreference_002.phpt b/ext/dom/tests/domdocument_createentityreference_002.phpt
new file mode 100644
index 0000000..a2416c2
--- /dev/null
+++ b/ext/dom/tests/domdocument_createentityreference_002.phpt
@@ -0,0 +1,17 @@
+--TEST--
+DomDocument::CreateEntityReference() - Empty Arguments
+--CREDITS--
+Clint Priest @ PhpTek09
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ $objDoc = new DomDocument();
+
+ $objRef = $objDoc->createEntityReference();
+?>
+===DONE===
+--EXPECTF--
+Warning: DOMDocument::createEntityReference() expects exactly 1 parameter, 0 given in %s
+===DONE===
+ \ No newline at end of file
diff --git a/ext/dom/tests/domelement.phpt b/ext/dom/tests/domelement.phpt
new file mode 100644
index 0000000..bc69af6
--- /dev/null
+++ b/ext/dom/tests/domelement.phpt
@@ -0,0 +1,114 @@
+--TEST--
+Elements: DOMElement functionality
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+$dom = new DOMDocument;
+$dom->loadXML($xmlstr);
+if(!$dom) {
+ echo "Error while parsing the document\n";
+ exit;
+}
+
+$node = $dom->documentElement;
+echo "Tag Name: ".$node->tagName."\n";
+
+
+$node->setAttribute('num', '1');
+echo "Chapter: ".$node->getAttribute('num')."\n";
+echo 'Attribute num exists?: '.($node->hasAttribute('num')?'Yes':'No')."\n";
+$node->removeAttribute('num');
+echo "Chapter: ".$node->getAttribute('num')."\n";
+echo 'Attribute num exists?: '.($node->hasAttribute('num')?'Yes':'No')."\n";
+
+echo "Language: ".$node->getAttribute('language')."\n";
+$lang = $node->getAttributeNode('language');
+$lang->nodeValue = 'en-US';
+$node->setAttributeNode($lang);
+echo "Language: ".$node->getAttribute('language')."\n";
+$node->removeAttributeNode($lang);
+echo "Language: ".$node->getAttribute('language')."\n";
+
+echo "\n-- xml:lang --\n";
+$node->setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang', 'en');
+echo "Language: ".$node->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')."\n";
+echo 'Attribute xml:lang exists?: '.($node->hasAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')?'Yes':'No')."\n";
+
+$node->removeAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang');
+echo "Language: ".$node->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')."\n";
+echo 'Attribute xml:lang exists?: '.($node->hasAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')?'Yes':'No')."\n";
+
+$lang = $dom->createAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang');
+$lang->nodeValue = 'en-GB';
+$node->setAttributeNodeNS($lang);
+unset($lang);
+echo "Language: ".$node->getAttributeNS('http://www.w3.org/XML/1998/namespace', 'lang')."\n";
+$lang = $node->getAttributeNodeNS('http://www.w3.org/XML/1998/namespace', 'lang');
+echo "Language: ".$lang->value."\n";
+
+echo "\n-- Elements --\n";
+$rows = $node->getElementsByTagName('row');
+echo "Row Count: ".$rows->length."\n";
+
+$element_ns = new DOMElement('newns:myelement', 'default content', 'urn::dummyns');
+$node->appendChild($element_ns);
+$element_ns = new DOMElement('newns2:myelement', 'second default content', 'urn::dummyns');
+$node->appendChild($element_ns);
+
+$myelements = $node->getElementsByTagNameNS('urn::dummyns', 'myelement');
+$mylen = $myelements->length;
+echo "myelements Count: ".$mylen."\n";
+
+echo "\n-- IDs --\n";
+$node->setAttribute('idatt', 'n1');
+$node->setIdAttribute('idatt', TRUE);
+
+for ($x = 0; $x < $mylen; $x++) {
+ $current = $myelements->item($x);
+ $current->setAttributeNS('urn::dummyns', 'newns:idatt', 'n'.($x+2))."\n";
+ $current->setIdAttributeNS('urn::dummyns', 'idatt', TRUE);
+}
+
+echo 'Element Name: '.(($elem = $dom->getElementByID('n1'))?$elem->localName:'Not Found')."\n";
+$idatt = $node->getAttributeNode('idatt');
+$node->setIdAttributeNode($idatt, FALSE);
+echo 'Element Name: '.(($elem = $dom->getElementByID('n1'))?$elem->localName:'Not Found')."\n";
+
+echo 'Element Name: '.(($elem = $dom->getElementByID('n3'))?$elem->nodeName:'Not Found')."\n";
+for ($x = 0; $x < $mylen; $x++) {
+ $node = $myelements->item($x);
+ $node->setIdAttributeNS('urn::dummyns', 'idatt', FALSE);
+}
+echo 'Element Name: '.(($elem = $dom->getElementByID('n3'))?$elem->nodeName:'Not Found')."\n";
+?>
+--EXPECT--
+
+Tag Name: chapter
+Chapter: 1
+Attribute num exists?: Yes
+Chapter:
+Attribute num exists?: No
+Language: en
+Language: en-US
+Language:
+
+-- xml:lang --
+Language: en
+Attribute xml:lang exists?: Yes
+Language:
+Attribute xml:lang exists?: No
+Language: en-GB
+Language: en-GB
+
+-- Elements --
+Row Count: 3
+myelements Count: 2
+
+-- IDs --
+Element Name: chapter
+Element Name: Not Found
+Element Name: newns2:myelement
+Element Name: Not Found
diff --git a/ext/dom/tests/domobject_debug_handler.phpt b/ext/dom/tests/domobject_debug_handler.phpt
new file mode 100644
index 0000000..3c9f133
--- /dev/null
+++ b/ext/dom/tests/domobject_debug_handler.phpt
@@ -0,0 +1,59 @@
+--TEST--
+Objects of DOM extension: debug info object handler.
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$xml = <<<XML
+<foo>
+ <bar>foobar</bar>
+</foo>
+XML;
+$d = new domdocument;
+$d->dynamicProperty = new stdclass;
+$d->loadXML($xml);
+print_r($d);
+--EXPECTF--
+DOMDocument Object
+(
+ [dynamicProperty] => stdClass Object
+ (
+ )
+
+ [doctype] =>
+ [implementation] => (object value omitted)
+ [documentElement] => (object value omitted)
+ [actualEncoding] =>
+ [encoding] =>
+ [xmlEncoding] =>
+ [standalone] => 1
+ [xmlStandalone] => 1
+ [version] => 1.0
+ [xmlVersion] => 1.0
+ [strictErrorChecking] => 1
+ [documentURI] => %s
+ [config] =>
+ [formatOutput] =>
+ [validateOnParse] =>
+ [resolveExternals] =>
+ [preserveWhiteSpace] => 1
+ [recover] =>
+ [substituteEntities] =>
+ [nodeName] => #document
+ [nodeValue] =>
+ [nodeType] => 9
+ [parentNode] =>
+ [childNodes] => (object value omitted)
+ [firstChild] => (object value omitted)
+ [lastChild] => (object value omitted)
+ [previousSibling] =>
+ [attributes] =>
+ [ownerDocument] =>
+ [namespaceURI] =>
+ [prefix] =>
+ [localName] =>
+ [baseURI] => %s
+ [textContent] =>
+ foobar
+
+)
diff --git a/ext/dom/tests/domxpath.phpt b/ext/dom/tests/domxpath.phpt
new file mode 100644
index 0000000..82396b5
--- /dev/null
+++ b/ext/dom/tests/domxpath.phpt
@@ -0,0 +1,58 @@
+--TEST--
+DOMXPath Tests
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+require_once("dom_test.inc");
+
+function MyAverage($nodelist) {
+ $count = 0;
+ $val = 0;
+ foreach ($nodelist AS $node) {
+ $count++;
+ $val += $node->textContent;
+ }
+ if ($val > 0) {
+ return $val/$count;
+ } else {
+ return 0;
+ }
+}
+
+$dom = new DOMDocument;
+$dom->loadXML(b'<root xmlns="urn::default"><child>myval</child></root>');
+
+$xpath = new DOMXPath($dom);
+
+$xpath->registerPHPFunctions('MyAverage');
+$xpath->registerNamespace("php", "http://php.net/xpath");
+
+$xpath->registerNamespace("def", "urn::default");
+$nodelist = $xpath->query("//def:child");
+if ($node = $nodelist->item(0)) {
+ print $node->textContent."\n";
+}
+
+$count = $xpath->evaluate("count(//def:child)");
+
+var_dump($count);
+
+$xpathdoc = $xpath->document;
+
+var_dump($xpathdoc instanceof DOMDocument);
+
+$root = $dom->documentElement;
+$root->appendChild($dom->createElementNS("urn::default", "testnode", 3));
+$root->appendChild($dom->createElementNS("urn::default", "testnode", 4));
+$root->appendChild($dom->createElementNS("urn::default", "testnode", 4));
+$root->appendChild($dom->createElementNS("urn::default", "testnode", 5));
+
+$avg = $xpath->evaluate('number(php:function("MyAverage", //def:testnode))');
+var_dump($avg);
+?>
+--EXPECT--
+myval
+float(1)
+bool(true)
+float(4) \ No newline at end of file
diff --git a/ext/dom/tests/note.dtd b/ext/dom/tests/note.dtd
new file mode 100644
index 0000000..c2d558e
--- /dev/null
+++ b/ext/dom/tests/note.dtd
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!ELEMENT note (to,from,heading,body)>
+<!ELEMENT to (#PCDATA)>
+<!ELEMENT from (#PCDATA)>
+<!ELEMENT heading (#PCDATA)>
+<!ELEMENT body (#PCDATA)>
diff --git a/ext/dom/tests/note.xml b/ext/dom/tests/note.xml
new file mode 100644
index 0000000..49614a1
--- /dev/null
+++ b/ext/dom/tests/note.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE note SYSTEM "note.dtd">
+<note>
+<to>PHP User Group</to>
+<from>Shane</from>
+<heading>Reminder</heading>
+<body>Don't forget the meeting tonight!</body>
+</note>
diff --git a/ext/dom/tests/nsdoc.xml b/ext/dom/tests/nsdoc.xml
new file mode 100644
index 0000000..9503fd8
--- /dev/null
+++ b/ext/dom/tests/nsdoc.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<root xmlns="http://ns" xmlns:ns2="http://ns2">
+ <ns2:child />
+</root> \ No newline at end of file
diff --git a/ext/dom/tests/regsiter_node_class.phpt b/ext/dom/tests/regsiter_node_class.phpt
new file mode 100644
index 0000000..c632c61
--- /dev/null
+++ b/ext/dom/tests/regsiter_node_class.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Test: registerNodeClass()
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+class myAttribute extends DOMAttr {
+ function testit() { return "HELLO Attribute"; }
+}
+
+class myElement extends DOMElement {
+ function testit() { return "HELLO Element"; }
+}
+
+$doc = new DOMDocument();
+$doc->registerNodeClass('DOMAttr', 'myAttribute');
+$doc->registerNodeClass('DOMElement', 'myElement');
+$doc->appendChild(new DOMElement('root'));
+$root = $doc->documentElement;
+$root->setAttribute('a', 'a1');
+echo get_class($root), "\n";
+print $root->testit()."\n";
+$attr = $root->getAttributeNode('a');
+echo get_class($attr), "\n";
+print $attr->testit()."\n";
+unset($attr);
+$doc->registerNodeClass('DOMAttr', NULL);
+$attr = $root->getAttributeNode('a');
+echo get_class($attr), "\n";
+print $attr->testit()."\n";
+?>
+--EXPECTF--
+
+myElement
+HELLO Element
+myAttribute
+HELLO Attribute
+DOMAttr
+
+Fatal error: Call to undefined method DOMAttr::testit() in %s on line 25
diff --git a/ext/dom/tests/skipif.inc b/ext/dom/tests/skipif.inc
new file mode 100644
index 0000000..08fd695
--- /dev/null
+++ b/ext/dom/tests/skipif.inc
@@ -0,0 +1 @@
+<?php if (!extension_loaded('dom')) die('skip dom extension not available');?> \ No newline at end of file
diff --git a/ext/dom/tests/test.html b/ext/dom/tests/test.html
new file mode 100644
index 0000000..fe6d0d3
--- /dev/null
+++ b/ext/dom/tests/test.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>Hello world</title>
+</head>
+<body>
+This is a not well-formed<br>
+html files with undeclared entities&nbsp;
+</body>
+</html>
diff --git a/ext/dom/tests/xinclude.xml b/ext/dom/tests/xinclude.xml
new file mode 100644
index 0000000..27efa91
--- /dev/null
+++ b/ext/dom/tests/xinclude.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<foo xmlns:xi="http://www.w3.org/2001/XInclude">
+ <xi:include href="compress.zlib://ext/dom/tests/book.xml#xpointer(/books/book)"/>
+ </foo>
diff --git a/ext/dom/text.c b/ext/dom/text.c
new file mode 100644
index 0000000..f608997
--- /dev/null
+++ b/ext/dom/text.c
@@ -0,0 +1,245 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+#include "dom_ce.h"
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_split_text, 0, 0, 1)
+ ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_is_whitespace_in_element_content, 0, 0, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_replace_whole_text, 0, 0, 1)
+ ZEND_ARG_INFO(0, content)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_text_construct, 0, 0, 0)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+/*
+* class DOMText extends DOMCharacterData
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-1312295772
+* Since:
+*/
+
+const zend_function_entry php_dom_text_class_functions[] = {
+ PHP_FALIAS(splitText, dom_text_split_text, arginfo_dom_text_split_text)
+ PHP_FALIAS(isWhitespaceInElementContent, dom_text_is_whitespace_in_element_content, arginfo_dom_text_is_whitespace_in_element_content)
+ PHP_FALIAS(isElementContentWhitespace, dom_text_is_whitespace_in_element_content, arginfo_dom_text_is_whitespace_in_element_content)
+ PHP_FALIAS(replaceWholeText, dom_text_replace_whole_text, arginfo_dom_text_replace_whole_text)
+ PHP_ME(domtext, __construct, arginfo_dom_text_construct, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+/* {{{ proto void DOMText::__construct([string value]); */
+PHP_METHOD(domtext, __construct)
+{
+
+ zval *id;
+ xmlNodePtr nodep = NULL, oldnode = NULL;
+ dom_object *intern;
+ char *value = NULL;
+ int value_len;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_text_class_entry, &value, &value_len) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ nodep = xmlNewText((xmlChar *) value);
+
+ if (!nodep) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldnode = dom_object_get_node(intern);
+ if (oldnode != NULL) {
+ php_libxml_node_free_resource(oldnode TSRMLS_CC);
+ }
+ php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
+ }
+}
+/* }}} end DOMText::__construct */
+
+/* {{{ wholeText string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-wholeText
+Since: DOM Level 3
+*/
+int dom_text_whole_text_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlNodePtr node;
+ xmlChar *wholetext = NULL;
+
+ node = dom_object_get_node(obj);
+
+ if (node == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 0 TSRMLS_CC);
+ return FAILURE;
+ }
+
+ /* Find starting text node */
+ while (node->prev && ((node->prev->type == XML_TEXT_NODE) || (node->prev->type == XML_CDATA_SECTION_NODE))) {
+ node = node->prev;
+ }
+
+ /* concatenate all adjacent text and cdata nodes */
+ while (node && ((node->type == XML_TEXT_NODE) || (node->type == XML_CDATA_SECTION_NODE))) {
+ wholetext = xmlStrcat(wholetext, node->content);
+ node = node->next;
+ }
+
+ ALLOC_ZVAL(*retval);
+ if (wholetext != NULL) {
+ ZVAL_STRING(*retval, wholetext, 1);
+ xmlFree(wholetext);
+ } else {
+ ZVAL_EMPTY_STRING(*retval);
+ }
+
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ proto DOMText dom_text_split_text(int offset);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-ID-38853C1D
+Since:
+*/
+PHP_FUNCTION(dom_text_split_text)
+{
+ zval *id;
+ xmlChar *cur;
+ xmlChar *first;
+ xmlChar *second;
+ xmlNodePtr node;
+ xmlNodePtr nnode;
+ long offset;
+ int ret;
+ int length;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &id, dom_text_class_entry, &offset) == FAILURE) {
+ return;
+ }
+ DOM_GET_OBJ(node, id, xmlNodePtr, intern);
+
+ if (node->type != XML_TEXT_NODE && node->type != XML_CDATA_SECTION_NODE) {
+ RETURN_FALSE;
+ }
+
+ cur = xmlNodeGetContent(node);
+ if (cur == NULL) {
+ RETURN_FALSE;
+ }
+ length = xmlUTF8Strlen(cur);
+
+ if (offset > length || offset < 0) {
+ xmlFree(cur);
+ RETURN_FALSE;
+ }
+
+ first = xmlUTF8Strndup(cur, offset);
+ second = xmlUTF8Strsub(cur, offset, length - offset);
+
+ xmlFree(cur);
+
+ xmlNodeSetContent(node, first);
+ nnode = xmlNewDocText(node->doc, second);
+
+ xmlFree(first);
+ xmlFree(second);
+
+ if (nnode == NULL) {
+ RETURN_FALSE;
+ }
+
+ if (node->parent != NULL) {
+ nnode->type = XML_ELEMENT_NODE;
+ xmlAddNextSibling(node, nnode);
+ nnode->type = XML_TEXT_NODE;
+ }
+
+ return_value = php_dom_create_object(nnode, &ret, return_value, intern TSRMLS_CC);
+}
+/* }}} end dom_text_split_text */
+
+/* {{{ proto boolean dom_text_is_whitespace_in_element_content();
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-isWhitespaceInElementContent
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_text_is_whitespace_in_element_content)
+{
+ zval *id;
+ xmlNodePtr node;
+ dom_object *intern;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_text_class_entry) == FAILURE) {
+ return;
+ }
+ DOM_GET_OBJ(node, id, xmlNodePtr, intern);
+
+ if (xmlIsBlankNode(node)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} end dom_text_is_whitespace_in_element_content */
+
+/* {{{ proto DOMText dom_text_replace_whole_text(string content);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#core-Text3-replaceWholeText
+Since: DOM Level 3
+*/
+PHP_FUNCTION(dom_text_replace_whole_text)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_text_replace_whole_text */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/typeinfo.c b/ext/dom/typeinfo.c
new file mode 100644
index 0000000..bc0e608
--- /dev/null
+++ b/ext/dom/typeinfo.c
@@ -0,0 +1,83 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/*
+* class domtypeinfo
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#TypeInfo
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_typeinfo_class_functions[] = {
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ type_name string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#TypeInfo-typeName
+Since:
+*/
+int dom_typeinfo_type_name_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* {{{ type_namespace string
+readonly=yes
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#TypeInfo-typeNamespace
+Since:
+*/
+int dom_typeinfo_type_namespace_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ ALLOC_ZVAL(*retval);
+ ZVAL_NULL(*retval);
+ return SUCCESS;
+}
+
+/* }}} */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/userdatahandler.c b/ext/dom/userdatahandler.c
new file mode 100644
index 0000000..d368a29
--- /dev/null
+++ b/ext/dom/userdatahandler.c
@@ -0,0 +1,66 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+
+/*
+* class domuserdatahandler
+*
+* URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#UserDataHandler
+* Since: DOM Level 3
+*/
+
+const zend_function_entry php_dom_userdatahandler_class_functions[] = {
+ PHP_FALIAS(handle, dom_userdatahandler_handle, NULL)
+ PHP_FE_END
+};
+
+/* {{{ attribute protos, not implemented yet */
+
+/* {{{ proto dom_void dom_userdatahandler_handle(short operation, string key, domobject data, node src, node dst);
+URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#ID-handleUserDataEvent
+Since:
+*/
+PHP_FUNCTION(dom_userdatahandler_handle)
+{
+ DOM_NOT_IMPLEMENTED();
+}
+/* }}} end dom_userdatahandler_handle */
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h
new file mode 100644
index 0000000..87a41c5
--- /dev/null
+++ b/ext/dom/xml_common.h
@@ -0,0 +1,106 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_XML_COMMON_H
+#define PHP_XML_COMMON_H
+
+#include "ext/libxml/php_libxml.h"
+
+typedef libxml_doc_props *dom_doc_propsptr;
+
+typedef struct _dom_object {
+ zend_object std;
+ void *ptr;
+ php_libxml_ref_obj *document;
+ HashTable *prop_handler;
+ zend_object_handle handle;
+} dom_object;
+
+#ifdef PHP_WIN32
+# ifdef PHPAPI
+# undef PHPAPI
+# endif
+# ifdef DOM_EXPORTS
+# define PHPAPI __declspec(dllexport)
+# else
+# define PHPAPI __declspec(dllimport)
+# endif /* DOM_EXPORTS */
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# ifdef PHPAPI
+# undef PHPAPI
+# endif
+# define PHPAPI __attribute__ ((visibility("default")))
+#endif /* PHP_WIN32 */
+
+#define PHP_DOM_EXPORT PHPAPI
+
+PHP_DOM_EXPORT extern zend_class_entry *dom_node_class_entry;
+PHP_DOM_EXPORT dom_object *php_dom_object_get_data(xmlNodePtr obj);
+PHP_DOM_EXPORT zval *php_dom_create_object(xmlNodePtr obj, int *found, zval* return_value, dom_object *domobj TSRMLS_DC);
+PHP_DOM_EXPORT xmlNodePtr dom_object_get_node(dom_object *obj);
+
+#define DOM_XMLNS_NAMESPACE \
+ (const xmlChar *) "http://www.w3.org/2000/xmlns/"
+
+#define NODE_GET_OBJ(__ptr, __id, __prtype, __intern) { \
+ __intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
+ if (__intern->node == NULL || !(__ptr = (__prtype)__intern->node->node)) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
+ RETURN_NULL();\
+ } \
+}
+
+#define DOC_GET_OBJ(__ptr, __id, __prtype, __intern) { \
+ __intern = (php_libxml_node_object *)zend_object_store_get_object(__id TSRMLS_CC); \
+ if (__intern->document != NULL) { \
+ if (!(__ptr = (__prtype)__intern->document->ptr)) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't fetch %s", __intern->std.ce->name);\
+ RETURN_NULL();\
+ } \
+ } \
+}
+
+#define DOM_RET_OBJ(obj, ret, domobject) \
+ if (!php_dom_create_object(obj, ret, return_value, domobject TSRMLS_CC)) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object"); \
+ RETURN_FALSE; \
+ }
+
+#define DOM_GET_THIS(zval) \
+ if (NULL == (zval = getThis())) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Underlying object missing"); \
+ RETURN_FALSE; \
+ }
+
+#define DOM_GET_THIS_OBJ(__ptr, __id, __prtype, __intern) \
+ DOM_GET_THIS(__id); \
+ DOM_GET_OBJ(__ptr, __id, __prtype, __intern);
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c
new file mode 100644
index 0000000..cf556a3
--- /dev/null
+++ b/ext/dom/xpath.c
@@ -0,0 +1,602 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Christian Stocker <chregu@php.net> |
+ | Rob Richards <rrichards@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#if HAVE_LIBXML && HAVE_DOM
+#include "php_dom.h"
+
+#define PHP_DOM_XPATH_QUERY 0
+#define PHP_DOM_XPATH_EVALUATE 1
+
+/*
+* class DOMXPath
+*/
+
+#if defined(LIBXML_XPATH_ENABLED)
+
+/* {{{ arginfo */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_construct, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, doc, DOMDocument, 0)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_ns, 0, 0, 2)
+ ZEND_ARG_INFO(0, prefix)
+ ZEND_ARG_INFO(0, uri)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_query, 0, 0, 1)
+ ZEND_ARG_INFO(0, expr)
+ ZEND_ARG_OBJ_INFO(0, context, DOMNode, 1)
+ ZEND_ARG_INFO(0, registerNodeNS)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_evaluate, 0, 0, 1)
+ ZEND_ARG_INFO(0, expr)
+ ZEND_ARG_OBJ_INFO(0, context, DOMNode, 1)
+ ZEND_ARG_INFO(0, registerNodeNS)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_dom_xpath_register_php_functions, 0, 0, 0)
+ZEND_END_ARG_INFO();
+/* }}} */
+
+const zend_function_entry php_dom_xpath_class_functions[] = {
+ PHP_ME(domxpath, __construct, arginfo_dom_xpath_construct, ZEND_ACC_PUBLIC)
+ PHP_FALIAS(registerNamespace, dom_xpath_register_ns, arginfo_dom_xpath_register_ns)
+ PHP_FALIAS(query, dom_xpath_query, arginfo_dom_xpath_query)
+ PHP_FALIAS(evaluate, dom_xpath_evaluate, arginfo_dom_xpath_evaluate)
+ PHP_FALIAS(registerPhpFunctions, dom_xpath_register_php_functions, arginfo_dom_xpath_register_php_functions)
+ PHP_FE_END
+};
+
+
+static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
+{
+ zval **args;
+ zval *retval;
+ int result, i, ret;
+ int error = 0;
+ zend_fcall_info fci;
+ zval handler;
+ xmlXPathObjectPtr obj;
+ char *str;
+ char *callable = NULL;
+ dom_xpath_object *intern;
+
+ TSRMLS_FETCH();
+
+ if (! zend_is_executing(TSRMLS_C)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlExtFunctionTest: Function called from outside of PHP\n");
+ error = 1;
+ } else {
+ intern = (dom_xpath_object *) ctxt->context->userData;
+ if (intern == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlExtFunctionTest: failed to get the internal object\n");
+ error = 1;
+ }
+ else if (intern->registerPhpFunctions == 0) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlExtFunctionTest: PHP Object did not register PHP functions\n");
+ error = 1;
+ }
+ }
+
+ if (error == 1) {
+ for (i = nargs - 1; i >= 0; i--) {
+ obj = valuePop(ctxt);
+ xmlXPathFreeObject(obj);
+ }
+ return;
+ }
+
+ fci.param_count = nargs - 1;
+ if (fci.param_count > 0) {
+ fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0);
+ args = safe_emalloc(fci.param_count, sizeof(zval *), 0);
+ }
+ /* Reverse order to pop values off ctxt stack */
+ for (i = nargs - 2; i >= 0; i--) {
+ obj = valuePop(ctxt);
+ MAKE_STD_ZVAL(args[i]);
+ switch (obj->type) {
+ case XPATH_STRING:
+ ZVAL_STRING(args[i], (char *)obj->stringval, 1);
+ break;
+ case XPATH_BOOLEAN:
+ ZVAL_BOOL(args[i], obj->boolval);
+ break;
+ case XPATH_NUMBER:
+ ZVAL_DOUBLE(args[i], obj->floatval);
+ break;
+ case XPATH_NODESET:
+ if (type == 1) {
+ str = (char *)xmlXPathCastToString(obj);
+ ZVAL_STRING(args[i], str, 1);
+ xmlFree(str);
+ } else if (type == 2) {
+ int j;
+ array_init(args[i]);
+ if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
+ for (j = 0; j < obj->nodesetval->nodeNr; j++) {
+ xmlNodePtr node = obj->nodesetval->nodeTab[j];
+ zval *child;
+ MAKE_STD_ZVAL(child);
+ /* not sure, if we need this... it's copied from xpath.c */
+ if (node->type == XML_NAMESPACE_DECL) {
+ xmlNsPtr curns;
+ xmlNodePtr nsparent;
+
+ nsparent = node->_private;
+ curns = xmlNewNs(NULL, node->name, NULL);
+ if (node->children) {
+ curns->prefix = xmlStrdup((xmlChar *) node->children);
+ }
+ if (node->children) {
+ node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name);
+ } else {
+ node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name);
+ }
+ node->type = XML_NAMESPACE_DECL;
+ node->parent = nsparent;
+ node->ns = curns;
+ }
+ child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC);
+ add_next_index_zval(args[i], child);
+ }
+ }
+ }
+ break;
+ default:
+ ZVAL_STRING(args[i], (char *)xmlXPathCastToString(obj), 1);
+ }
+ xmlXPathFreeObject(obj);
+ fci.params[i] = &args[i];
+ }
+
+ fci.size = sizeof(fci);
+ fci.function_table = EG(function_table);
+
+ obj = valuePop(ctxt);
+ if (obj->stringval == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string");
+ xmlXPathFreeObject(obj);
+ if (fci.param_count > 0) {
+ for (i = 0; i < nargs - 1; i++) {
+ zval_ptr_dtor(&args[i]);
+ }
+ efree(args);
+ efree(fci.params);
+ }
+ return;
+ }
+ INIT_PZVAL(&handler);
+ ZVAL_STRING(&handler, obj->stringval, 1);
+ xmlXPathFreeObject(obj);
+
+ fci.function_name = &handler;
+ fci.symbol_table = NULL;
+ fci.object_ptr = NULL;
+ fci.retval_ptr_ptr = &retval;
+ fci.no_separation = 0;
+
+ if (!zend_make_callable(&handler, &callable TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable);
+
+ } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable);
+ /* Push an empty string, so that we at least have an xslt result... */
+ valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
+ } else {
+ result = zend_call_function(&fci, NULL TSRMLS_CC);
+ if (result == FAILURE) {
+ if (Z_TYPE(handler) == IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler));
+ }
+ /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
+ } else if (retval == NULL) {
+ } else {
+ if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
+ xmlNode *nodep;
+ dom_object *obj;
+ if (intern->node_list == NULL) {
+ ALLOC_HASHTABLE(intern->node_list);
+ zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
+ }
+ zval_add_ref(&retval);
+ zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
+ obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
+ nodep = dom_object_get_node(obj);
+ valuePush(ctxt, xmlXPathNewNodeSet(nodep));
+ } else if (retval->type == IS_BOOL) {
+ valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
+ } else if (retval->type == IS_OBJECT) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
+ valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
+ } else {
+ convert_to_string_ex(&retval);
+ valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
+ }
+ zval_ptr_dtor(&retval);
+ }
+ }
+ efree(callable);
+ zval_dtor(&handler);
+ if (fci.param_count > 0) {
+ for (i = 0; i < nargs - 1; i++) {
+ zval_ptr_dtor(&args[i]);
+ }
+ efree(args);
+ efree(fci.params);
+ }
+}
+/* }}} */
+
+static void dom_xpath_ext_function_string_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
+{
+ dom_xpath_ext_function_php(ctxt, nargs, 1);
+}
+/* }}} */
+
+static void dom_xpath_ext_function_object_php(xmlXPathParserContextPtr ctxt, int nargs) /* {{{ */
+{
+ dom_xpath_ext_function_php(ctxt, nargs, 2);
+}
+/* }}} */
+
+/* {{{ proto void DOMXPath::__construct(DOMDocument doc) U */
+PHP_METHOD(domxpath, __construct)
+{
+ zval *id, *doc;
+ xmlDocPtr docp = NULL;
+ dom_object *docobj;
+ dom_xpath_object *intern;
+ xmlXPathContextPtr ctx, oldctx;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_xpath_class_entry, &doc, dom_document_class_entry) == FAILURE) {
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ return;
+ }
+
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+ DOM_GET_OBJ(docp, doc, xmlDocPtr, docobj);
+
+ ctx = xmlXPathNewContext(docp);
+ if (ctx == NULL) {
+ php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
+ if (intern != NULL) {
+ oldctx = (xmlXPathContextPtr)intern->ptr;
+ if (oldctx != NULL) {
+ php_libxml_decrement_doc_ref((php_libxml_node_object *)intern TSRMLS_CC);
+ xmlXPathFreeContext(oldctx);
+ }
+
+ xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "functionString",
+ (const xmlChar *) "http://php.net/xpath",
+ dom_xpath_ext_function_string_php);
+ xmlXPathRegisterFuncNS (ctx, (const xmlChar *) "function",
+ (const xmlChar *) "http://php.net/xpath",
+ dom_xpath_ext_function_object_php);
+
+ intern->ptr = ctx;
+ ctx->userData = (void *)intern;
+ intern->document = docobj->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)intern, docp TSRMLS_CC);
+ }
+}
+/* }}} end DOMXPath::__construct */
+
+/* {{{ document DOMDocument*/
+int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC)
+{
+ xmlDoc *docp = NULL;
+ xmlXPathContextPtr ctx;
+ int ret;
+ zval *tmp;
+
+ ctx = (xmlXPathContextPtr) obj->ptr;
+
+ if (ctx) {
+ docp = (xmlDocPtr) ctx->doc;
+ }
+
+ ALLOC_ZVAL(*retval);
+ tmp = *retval;
+
+ if (NULL == (*retval = php_dom_create_object((xmlNodePtr) docp, &ret, *retval, obj TSRMLS_CC))) {
+ FREE_ZVAL(tmp);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create required DOM object");
+ return FAILURE;
+ }
+ if (tmp != *retval) {
+ FREE_ZVAL(tmp);
+ }
+ 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_xpath_object *intern;
+ unsigned char *prefix, *ns_uri;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oss", &id, dom_xpath_class_entry, &prefix, &prefix_len, &ns_uri, &ns_uri_len) == FAILURE) {
+ return;
+ }
+
+ intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ ctxp = (xmlXPathContextPtr) intern->ptr;
+ if (ctxp == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context");
+ RETURN_FALSE;
+ }
+
+ if (xmlXPathRegisterNs(ctxp, prefix, ns_uri) != 0) {
+ RETURN_FALSE
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+static void dom_xpath_iter(zval *baseobj, dom_object *intern) /* {{{ */
+{
+ dom_nnodemap_object *mapptr;
+
+ mapptr = (dom_nnodemap_object *)intern->ptr;
+ mapptr->baseobjptr = baseobj;
+ mapptr->nodetype = DOM_NODESET;
+
+}
+/* }}} */
+
+static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
+{
+ zval *id, *retval, *context = NULL;
+ xmlXPathContextPtr ctxp;
+ xmlNodePtr nodep = NULL;
+ xmlXPathObjectPtr xpathobjp;
+ int expr_len, ret, nsnbr = 0, xpath_type;
+ dom_xpath_object *intern;
+ dom_object *nodeobj;
+ char *expr;
+ xmlDoc *docp = NULL;
+ xmlNsPtr *ns = NULL;
+ zend_bool register_node_ns = 1;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|O!b", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry, &register_node_ns) == FAILURE) {
+ return;
+ }
+
+ intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ ctxp = (xmlXPathContextPtr) intern->ptr;
+ if (ctxp == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Context");
+ RETURN_FALSE;
+ }
+
+ docp = (xmlDocPtr) ctxp->doc;
+ if (docp == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid XPath Document Pointer");
+ RETURN_FALSE;
+ }
+
+ if (context != NULL) {
+ DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj);
+ }
+
+ if (!nodep) {
+ nodep = xmlDocGetRootElement(docp);
+ }
+
+ if (nodep && docp != nodep->doc) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Node From Wrong Document");
+ RETURN_FALSE;
+ }
+
+ ctxp->node = nodep;
+
+ if (register_node_ns) {
+ /* 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 (ns != NULL) {
+ xmlFree(ns);
+ ctxp->namespaces = NULL;
+ ctxp->nsNr = 0;
+ }
+
+ if (! xpathobjp) {
+ RETURN_FALSE;
+ }
+
+ if (type == PHP_DOM_XPATH_QUERY) {
+ xpath_type = XPATH_NODESET;
+ } else {
+ xpath_type = xpathobjp->type;
+ }
+
+ switch (xpath_type) {
+
+ case XPATH_NODESET:
+ {
+ int i;
+ xmlNodeSetPtr nodesetp;
+
+ MAKE_STD_ZVAL(retval);
+ array_init(retval);
+
+ if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) {
+
+ for (i = 0; i < nodesetp->nodeNr; i++) {
+ xmlNodePtr node = nodesetp->nodeTab[i];
+ zval *child;
+
+ MAKE_STD_ZVAL(child);
+
+ if (node->type == XML_NAMESPACE_DECL) {
+ xmlNsPtr curns;
+ xmlNodePtr nsparent;
+
+ nsparent = node->_private;
+ curns = xmlNewNs(NULL, node->name, NULL);
+ if (node->children) {
+ curns->prefix = xmlStrdup((char *) node->children);
+ }
+ if (node->children) {
+ node = xmlNewDocNode(docp, NULL, (char *) node->children, node->name);
+ } else {
+ node = xmlNewDocNode(docp, NULL, "xmlns", node->name);
+ }
+ node->type = XML_NAMESPACE_DECL;
+ node->parent = nsparent;
+ node->ns = curns;
+ }
+ child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC);
+ add_next_index_zval(retval, child);
+ }
+ }
+ php_dom_create_interator(return_value, DOM_NODELIST TSRMLS_CC);
+ nodeobj = (dom_object *)zend_objects_get_address(return_value TSRMLS_CC);
+ dom_xpath_iter(retval, nodeobj);
+ break;
+ }
+
+ case XPATH_BOOLEAN:
+ RETVAL_BOOL(xpathobjp->boolval);
+ break;
+
+ case XPATH_NUMBER:
+ RETVAL_DOUBLE(xpathobjp->floatval)
+ break;
+
+ case XPATH_STRING:
+ RETVAL_STRING(xpathobjp->stringval, 1);
+ break;
+
+ default:
+ RETVAL_NULL();
+ break;
+ }
+
+ xmlXPathFreeObject(xpathobjp);
+}
+/* }}} */
+
+/* {{{ proto DOMNodeList dom_xpath_query(string expr [,DOMNode context [, boolean registerNodeNS]]); */
+PHP_FUNCTION(dom_xpath_query)
+{
+ php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_QUERY);
+}
+/* }}} end dom_xpath_query */
+
+/* {{{ proto mixed dom_xpath_evaluate(string expr [,DOMNode context [, boolean registerNodeNS]]); */
+PHP_FUNCTION(dom_xpath_evaluate)
+{
+ php_xpath_eval(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_DOM_XPATH_EVALUATE);
+}
+/* }}} end dom_xpath_evaluate */
+
+/* {{{ proto void dom_xpath_register_php_functions() */
+PHP_FUNCTION(dom_xpath_register_php_functions)
+{
+ zval *id;
+ dom_xpath_object *intern;
+ zval *array_value, **entry, *new_string;
+ int name_len = 0;
+ char *name;
+
+ DOM_GET_THIS(id);
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "a", &array_value) == SUCCESS) {
+ intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
+ zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value));
+
+ while (zend_hash_get_current_data(Z_ARRVAL_P(array_value), (void **)&entry) == SUCCESS) {
+ SEPARATE_ZVAL(entry);
+ convert_to_string_ex(entry);
+
+ MAKE_STD_ZVAL(new_string);
+ ZVAL_LONG(new_string,1);
+
+ zend_hash_update(intern->registered_phpfunctions, Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &new_string, sizeof(zval*), NULL);
+ zend_hash_move_forward(Z_ARRVAL_P(array_value));
+ }
+ intern->registerPhpFunctions = 2;
+ RETURN_TRUE;
+
+ } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == SUCCESS) {
+ intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
+
+ MAKE_STD_ZVAL(new_string);
+ ZVAL_LONG(new_string,1);
+ zend_hash_update(intern->registered_phpfunctions, name, name_len + 1, &new_string, sizeof(zval*), NULL);
+ intern->registerPhpFunctions = 2;
+
+ } else {
+ intern = (dom_xpath_object *)zend_object_store_get_object(id TSRMLS_CC);
+ intern->registerPhpFunctions = 1;
+ }
+
+}
+/* }}} end dom_xpath_register_php_functions */
+
+#endif /* LIBXML_XPATH_ENABLED */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */