diff options
Diffstat (limited to 'ext/dom/element.c')
| -rw-r--r-- | ext/dom/element.c | 271 |
1 files changed, 229 insertions, 42 deletions
diff --git a/ext/dom/element.c b/ext/dom/element.c index 2be0e8f31..1d5bbc120 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: element.c,v 1.36.2.4 2006/05/03 08:43:04 rrichards Exp $ */ +/* $Id: element.c,v 1.36.2.4.2.6 2006/09/28 10:11:36 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -88,7 +88,7 @@ PHP_METHOD(domelement, __construct) if (uri_len > 0) { errorcode = dom_check_qname(name, &localname, &prefix, uri_len, name_len); if (errorcode == 0) { - nodep = xmlNewNode (NULL, localname); + nodep = xmlNewNode (NULL, (xmlChar *)localname); if (nodep != NULL && uri != NULL) { nsptr = dom_get_ns(nodep, uri, &errorcode, prefix); xmlSetNs(nodep, nsptr); @@ -100,14 +100,14 @@ PHP_METHOD(domelement, __construct) } if (errorcode != 0) { if (nodep != NULL) { - xmlFree(nodep); + 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(name, (xmlChar **) &prefix); + localname = xmlSplitQName2((xmlChar *)name, (xmlChar **) &prefix); if (prefix != NULL) { xmlFree(localname); xmlFree(prefix); @@ -123,7 +123,7 @@ PHP_METHOD(domelement, __construct) } if (value_len > 0) { - xmlNodeSetContentLen(nodep, value, value_len); + xmlNodeSetContentLen(nodep, (xmlChar *) value, value_len); } intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC); @@ -161,7 +161,7 @@ int dom_element_tag_name_read(dom_object *obj, zval **retval TSRMLS_DC) qname = xmlStrdup(ns->prefix); qname = xmlStrcat(qname, ":"); qname = xmlStrcat(qname, nodep->name); - ZVAL_STRING(*retval, qname, 1); + ZVAL_STRING(*retval, (char *)qname, 1); xmlFree(qname); } else { ZVAL_STRING(*retval, (char *) nodep->name, 1); @@ -188,7 +188,46 @@ int dom_element_schema_type_info_read(dom_object *obj, zval **retval TSRMLS_DC) /* }}} */ - +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, "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, "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 @@ -198,8 +237,9 @@ PHP_FUNCTION(dom_element_get_attribute) { zval *id; xmlNode *nodep; - char *name, *value; + char *name, *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) { @@ -208,7 +248,20 @@ PHP_FUNCTION(dom_element_get_attribute) DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); - value = xmlGetProp(nodep, name); + 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 { @@ -227,12 +280,11 @@ PHP_FUNCTION(dom_element_set_attribute) { zval *id, *rv = NULL; xmlNode *nodep; - xmlAttr *attr; + xmlNodePtr attr = NULL; int ret, name_len, value_len; 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; } @@ -249,17 +301,33 @@ PHP_FUNCTION(dom_element_set_attribute) RETURN_FALSE; } - attr = xmlHasProp(nodep,name); - if (attr != NULL && attr->type != XML_ATTRIBUTE_DECL) { + 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, "xmlns")) { + if (xmlNewNs(nodep, (xmlChar *)value, NULL)) { + RETURN_TRUE; + } + } else { + attr = (xmlNodePtr)xmlSetProp(nodep, (xmlChar *) name, value); } - attr = xmlSetProp(nodep, name, value); if (!attr) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such attribute '%s'", name); RETURN_FALSE; } - DOM_RET_OBJ(rv, (xmlNodePtr) attr, &ret, intern); + DOM_RET_OBJ(rv, attr, &ret, intern); } /* }}} end dom_element_set_attribute */ @@ -272,8 +340,7 @@ Since: PHP_FUNCTION(dom_element_remove_attribute) { zval *id; - xmlNode *nodep; - xmlAttr *attrp; + xmlNodePtr nodep, attrp; dom_object *intern; int name_len; char *name; @@ -289,19 +356,25 @@ PHP_FUNCTION(dom_element_remove_attribute) RETURN_FALSE; } - attrp = xmlHasProp(nodep,name); + attrp = dom_get_dom1_attribute(nodep, (xmlChar *)name); if (attrp == NULL) { RETURN_FALSE; } - if (attrp->type != XML_ATTRIBUTE_DECL) { - if (php_dom_object_get_data((xmlNodePtr) attrp) == NULL) { + switch (attrp->type) { + case XML_ATTRIBUTE_NODE: + if (php_dom_object_get_data(attrp) == NULL) { node_list_unlink(attrp->children TSRMLS_CC); - xmlUnlinkNode((xmlNodePtr) attrp); - xmlFreeProp(attrp); + xmlUnlinkNode(attrp); + xmlFreeProp((xmlAttrPtr)attrp); } else { - xmlUnlinkNode((xmlNodePtr) attrp); + xmlUnlinkNode(attrp); } + break; + case XML_NAMESPACE_DECL: + RETURN_FALSE; + default: + break; } RETURN_TRUE; @@ -316,8 +389,7 @@ Since: PHP_FUNCTION(dom_element_get_attribute_node) { zval *id, *rv = NULL; - xmlNode *nodep; - xmlAttr *attrp; + xmlNodePtr nodep, attrp; int name_len, ret; dom_object *intern; char *name; @@ -328,11 +400,30 @@ PHP_FUNCTION(dom_element_get_attribute_node) DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); - attrp = xmlHasProp(nodep,name); + 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, "xmlns", attrp->name); + } + attrp->type = XML_NAMESPACE_DECL; + attrp->parent = nsparent; + attrp->ns = curns; + } + DOM_RET_OBJ(rv, (xmlNodePtr) attrp, &ret, intern); } /* }}} end dom_element_get_attribute_node */ @@ -485,13 +576,13 @@ PHP_FUNCTION(dom_element_get_attribute_ns) DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); - strattr = xmlGetNsProp(elemp, name, uri); + strattr = xmlGetNsProp(elemp, (xmlChar *) name, (xmlChar *) uri); if (strattr != NULL) { RETVAL_STRING(strattr, 1); xmlFree(strattr); } else { - if (xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { + if (xmlStrEqual((xmlChar *) uri, DOM_XMLNS_NAMESPACE)) { nsptr = dom_get_nsdecl(elemp, name); if (nsptr != NULL) { RETVAL_STRING((char *) nsptr->href, 1); @@ -581,12 +672,12 @@ PHP_FUNCTION(dom_element_set_attribute_ns) if (errorcode == 0) { if (uri_len > 0) { - nodep = (xmlNodePtr) xmlHasNsProp(elemp, localname, uri); + 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(prefix,"xmlns") && xmlStrEqual(uri, DOM_XMLNS_NAMESPACE)) { + if (xmlStrEqual((xmlChar *) prefix,"xmlns") && xmlStrEqual((xmlChar *) uri, DOM_XMLNS_NAMESPACE)) { is_xmlns = 1; nsptr = dom_get_nsdecl(elemp, localname); } else { @@ -679,11 +770,11 @@ PHP_FUNCTION(dom_element_remove_attribute_ns) RETURN_NULL(); } - attrp = xmlHasNsProp(nodep, name, uri); + attrp = xmlHasNsProp(nodep, (xmlChar *)name, (xmlChar *)uri); - nsptr = dom_get_nsdecl(nodep, name); + nsptr = dom_get_nsdecl(nodep, (xmlChar *)name); if (nsptr != NULL) { - if (xmlStrEqual(uri, nsptr->href)) { + if (xmlStrEqual((xmlChar *)uri, nsptr->href)) { if (nsptr->href != NULL) { xmlFree((char *) nsptr->href); nsptr->href = NULL; @@ -852,8 +943,9 @@ PHP_FUNCTION(dom_element_has_attribute) zval *id; xmlNode *nodep; dom_object *intern; - char *name, *value; + 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; @@ -861,11 +953,10 @@ PHP_FUNCTION(dom_element_has_attribute) DOM_GET_OBJ(nodep, id, xmlNodePtr, intern); - value = xmlGetProp(nodep, name); - if (value == NULL) { + attr = dom_get_dom1_attribute(nodep, (xmlChar *)name); + if (attr == NULL) { RETURN_FALSE; } else { - xmlFree(value); RETURN_TRUE; } } @@ -883,7 +974,8 @@ PHP_FUNCTION(dom_element_has_attribute_ns) xmlNs *nsp; dom_object *intern; int uri_len, name_len; - char *uri, *name, *value; + 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; @@ -891,7 +983,7 @@ PHP_FUNCTION(dom_element_has_attribute_ns) DOM_GET_OBJ(elemp, id, xmlNodePtr, intern); - value = xmlGetNsProp(elemp, name, uri); + value = xmlGetNsProp(elemp, (xmlChar *)name, (xmlChar *)uri); if (value != NULL) { xmlFree(value); @@ -910,13 +1002,57 @@ PHP_FUNCTION(dom_element_has_attribute_ns) /* }}} 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) { - DOM_NOT_IMPLEMENTED(); + 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, 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 */ @@ -927,7 +1063,33 @@ Since: DOM Level 3 */ PHP_FUNCTION(dom_element_set_id_attribute_ns) { - DOM_NOT_IMPLEMENTED(); + 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 */ @@ -938,7 +1100,32 @@ Since: DOM Level 3 */ PHP_FUNCTION(dom_element_set_id_attribute_node) { - DOM_NOT_IMPLEMENTED(); + 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 */ |
