summaryrefslogtreecommitdiff
path: root/ext/domxml/php_domxml.c
diff options
context:
space:
mode:
authorUwe Steinmann <steinm@php.net>2002-04-23 06:05:38 +0000
committerUwe Steinmann <steinm@php.net>2002-04-23 06:05:38 +0000
commitd4c273c3a7b8939e9564d0e729de0180cac2b564 (patch)
tree7e9b53aec62e8b0dc48fa50722102e579bdaa6d9 /ext/domxml/php_domxml.c
parentcab34e6b055f3215886d9dd181e85953fc001b8d (diff)
downloadphp-git-d4c273c3a7b8939e9564d0e729de0180cac2b564.tar.gz
- get_element_by_id() doesn't use xpath anymore but searches in
xmlDoc->ids as provided by libxml. - New function DomDocument->ids() returns a list of ids (subject to change) - replace_node() doesn't make a copy of the new node if it has no parents
Diffstat (limited to 'ext/domxml/php_domxml.c')
-rw-r--r--ext/domxml/php_domxml.c157
1 files changed, 91 insertions, 66 deletions
diff --git a/ext/domxml/php_domxml.c b/ext/domxml/php_domxml.c
index 8299b7d7c4..2dc1eda5dc 100644
--- a/ext/domxml/php_domxml.c
+++ b/ext/domxml/php_domxml.c
@@ -258,7 +258,6 @@ static zend_function_entry domxml_functions[] = {
static function_entry php_domxmldoc_class_functions[] = {
PHP_FALIAS(doctype, domxml_doc_doctype, NULL)
PHP_FALIAS(implementation, domxml_doc_implementation, NULL)
- PHP_FALIAS(root, domxml_doc_document_element, NULL) /* not DOM */
PHP_FALIAS(document_element, domxml_doc_document_element, NULL)
PHP_FALIAS(create_element, domxml_doc_create_element, NULL)
PHP_FALIAS(create_text_node, domxml_doc_create_text_node, NULL)
@@ -269,11 +268,14 @@ static function_entry php_domxmldoc_class_functions[] = {
PHP_FALIAS(create_processing_instruction, domxml_doc_create_processing_instruction, NULL)
PHP_FALIAS(get_elements_by_tagname, domxml_doc_get_elements_by_tagname, NULL)
PHP_FALIAS(get_element_by_id, domxml_doc_get_element_by_id, NULL)
+ /* Everything below this comment is none DOM compliant */
/* children is deprecated because it is inherited from DomNode */
/* PHP_FALIAS(children, domxml_node_children, NULL) */
+ PHP_FALIAS(root, domxml_doc_document_element, NULL)
PHP_FALIAS(add_root, domxml_add_root, NULL)
PHP_FALIAS(imported_node, domxml_doc_imported_node, NULL)
PHP_FALIAS(dtd, domxml_intdtd, NULL)
+ PHP_FALIAS(ids, domxml_doc_ids, NULL)
PHP_FALIAS(dumpmem, domxml_dump_mem, NULL)
PHP_FALIAS(dump_mem, domxml_dump_mem, NULL)
PHP_FALIAS(dump_mem_file, domxml_dump_mem_file, NULL)
@@ -2007,9 +2009,18 @@ PHP_FUNCTION(domxml_node_replace_node)
DOMXML_GET_OBJ(repnode, node, le_domxmlnodep);
- if (NULL == (new_repnode = xmlCopyNode(repnode, 1))) {
- php_error(E_WARNING, "%s(): unable to clone node", get_active_function_name(TSRMLS_C));
- RETURN_FALSE;
+ /* check if the new node is already part of the document. In such a case
+ * we better make a copy to prevent changing identical nodes at different
+ * positions in the document at the same time.
+ * A node created with e.g. create_element() doesn't have parents.
+ */
+ if(repnode->parent) {
+ if (NULL == (new_repnode = xmlCopyNode(repnode, 1))) {
+ php_error(E_WARNING, "%s(): unable to clone node", get_active_function_name(TSRMLS_C));
+ RETURN_FALSE;
+ }
+ } else {
+ new_repnode = repnode;
}
repnode = xmlReplaceNode(nodep, new_repnode);
@@ -2635,77 +2646,47 @@ PHP_FUNCTION(domxml_doc_get_elements_by_tagname)
}
/* }}} */
-/* {{{ proto string domxml_doc_get_element_by_id(string id [,object xpathctx_handle] )
+typedef struct _idsIterator idsIterator;
+struct _idsIterator {
+ xmlChar *elementId;
+ xmlNode *element;
+};
+
+static void idsHashScanner(void *payload, void *data, xmlChar *name) {
+ idsIterator *priv = (idsIterator *)data;
+
+ if (priv->element == NULL && xmlStrEqual (name, priv->elementId))
+ priv->element = ((xmlNode *)((xmlID *)payload)->attr)->parent;
+}
+
+/* {{{ proto string domxml_doc_get_element_by_id(string id)
Returns element for given id or false if not found */
PHP_FUNCTION(domxml_doc_get_element_by_id)
{
- zval *id, *rv = NULL, *contextnode = NULL, *ctxpin = NULL;
- xmlXPathContextPtr ctxp ;
+ zval *id, *rv = NULL;
xmlDocPtr docp;
+ idsIterator iter;
+ xmlHashTable *ids = NULL;
+ int retnode;
- xmlXPathObjectPtr xpathobjp;
- xmlNode *contextnodep;
int name_len;
char *str, *name;
- contextnode = NULL;
- contextnodep = NULL;
+ id = getThis();
+ DOMXML_GET_OBJ(docp, id, le_domxmldocp);
- DOMXML_PARAM_FOUR(docp, id, le_domxmldocp, "s|oo", &name, &name_len,&ctxpin,&contextnodep);
-
- /* if no xpath_context was submitted, create a new one */
- if (ctxpin == NULL) {
- ctxp = xmlXPathNewContext(docp);
+ ids = (xmlHashTable *) docp->ids;
+ if(ids) {
+ iter.elementId = (xmlChar *)
+ iter.element = NULL;
+ xmlHashScan(ids, idsHashScanner, &iter);
+ rv = php_domobject_new(iter.element, &retnode TSRMLS_CC);
+ SEPARATE_ZVAL(&rv);
+ *return_value = *rv;
+ FREE_ZVAL(rv);
} else {
- DOMXML_GET_OBJ(ctxp, ctxpin, le_xpathctxp);
- }
-
- if (contextnode) {
- DOMXML_GET_OBJ(contextnodep, contextnode, le_domxmlnodep);
- }
- ctxp->node = contextnodep;
- str = (char*) emalloc((name_len+14) * sizeof(char)) ;
- if (str == NULL) {
- php_error(E_WARNING, "%s(): cannot allocate memory for string", get_active_function_name(TSRMLS_C));
- }
- sprintf(str ,"//*[@ID = '%s']",name);
- xpathobjp = xmlXPathEval(str, ctxp);
- efree(str);
- ctxp->node = NULL;
- if (!xpathobjp) {
RETURN_FALSE;
}
-
- switch (Z_TYPE_P(xpathobjp)) {
-
- case XPATH_NODESET:
- {
- xmlNodeSetPtr nodesetp;
-
- if (NULL == (nodesetp = xpathobjp->nodesetval)) {
- zval_dtor(rv);
- RETURN_FALSE;
- }
-
- if (nodesetp->nodeNr > 0) {
- xmlNodePtr node = nodesetp->nodeTab[0];
- int retnode;
- rv = php_domobject_new(node, &retnode TSRMLS_CC);
- SEPARATE_ZVAL(&rv);
- }
- else {
- /*return false, if no nodes were found */
- RETURN_FALSE;
- }
-
- break;
- }
- default:
- break;
- }
-
- *return_value = *rv;
- FREE_ZVAL(rv);
}
/* }}} */
#endif
@@ -3273,6 +3254,40 @@ PHP_FUNCTION(domxml_dump_node)
}
/* }}} */
+static void idsHashScanner2(void *payload, void *data, xmlChar *name) {
+ zval *return_value = (zval *) data;
+ zval *child;
+ int ret;
+ xmlNode *nodep;
+
+ nodep = ((xmlNode *)((xmlID *)payload)->attr)->parent;
+ child = php_domobject_new(nodep, &ret TSRMLS_CC);
+ add_next_index_zval(return_value, child);
+}
+
+/* {{{ proto string domxml_doc_ids(object doc_handle)
+ Returns array of ids */
+PHP_FUNCTION(domxml_doc_ids)
+{
+ zval *id;
+ xmlDoc *docp;
+ xmlHashTable *ids = NULL;
+
+ DOMXML_GET_THIS_OBJ(docp, id, le_domxmldocp);
+
+ ids = docp->ids;
+
+ if(ids) {
+ if (array_init(return_value) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ xmlHashScan(ids, idsHashScanner2, return_value);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
/* {{{ proto object xmldoc(string xmldoc [, bool from_file])
Creates DOM object of XML document */
@@ -3284,10 +3299,14 @@ PHP_FUNCTION(xmldoc)
char *buffer;
int buffer_len;
zend_bool from_file = 0;
+ xmlDtdPtr dtd;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &buffer, &buffer_len, &from_file) == FAILURE) {
return;
}
+/* Either of the following line force validation */
+/* xmlLoadExtDtdDefaultValue = XML_DETECT_IDS; */
+/* xmlDoValidityCheckingDefaultValue = 1; */
if (from_file) {
docp = xmlParseFile(buffer);
@@ -3297,6 +3316,11 @@ PHP_FUNCTION(xmldoc)
if (!docp)
RETURN_FALSE;
+/* dtd = xmlGetIntSubset(docp);
+ if(dtd) {
+ xmlParseDTD(dtd->ExternalID, dtd->SystemID);
+ }
+*/
DOMXML_RET_OBJ(rv, (xmlNodePtr) docp, &ret);
}
/* }}} */
@@ -3507,7 +3531,7 @@ PHP_FUNCTION(domxml_new_xmldoc)
}
/* }}} */
-/* {{{ proto object domxml_parer([string buf[,string filename]])
+/* {{{ proto object domxml_parser([string buf[,string filename]])
Creates new xmlparser */
PHP_FUNCTION(domxml_parser)
{
@@ -3522,10 +3546,11 @@ PHP_FUNCTION(domxml_parser)
return;
}
- parserp = xmlCreatePushParserCtxt(NULL, NULL, buf, buf_len , filename);
+ parserp = xmlCreatePushParserCtxt(NULL, NULL, buf, buf_len, filename);
if (!parserp) {
RETURN_FALSE;
}
+/* parserp->loadsubset = XML_DETECT_IDS; */
rv = php_xmlparser_new(parserp, &ret TSRMLS_CC);
DOMXML_RET_ZVAL(rv);
@@ -4007,7 +4032,7 @@ static zval *php_xsltstylesheet_new(xsltStylesheetPtr obj, int *found TSRMLS_DC)
zval *wrapper;
int rsrc_type;
- *found = 0;
+ *found = 0;
if (!obj) {
MAKE_STD_ZVAL(wrapper);