Index: simplexml.c =================================================================== RCS file: /repository/php-src/ext/simplexml/simplexml.c,v retrieving revision 1.198 diff -u -d -p -r1.198 simplexml.c --- simplexml.c 5 Mar 2006 14:01:13 -0000 1.198 +++ simplexml.c 5 Mar 2006 14:11:38 -0000 @@ -1403,6 +1403,129 @@ SXE_METHOD(attributes) } /* }}} */ +/* {{{ proto object SimpleXMLElement::addChild(string qName, string value [,string ns]) + Add Element with optional namespace information */ +SXE_METHOD(addChild) +{ + php_sxe_object *sxe; + char *qname, *value = NULL, *nsuri = NULL; + int qname_len, value_len = 0, nsuri_len = 0; + xmlNodePtr node, newnode; + xmlNsPtr nsptr = NULL; + xmlChar *localname, *prefix = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s!s!", + &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) { + return; + } + + if (qname_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Element name is required"); + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + + if (sxe->iter.type == SXE_ITER_ATTRLIST) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to attributes"); + return; + } + + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + localname = xmlSplitQName2(qname, &prefix); + if (localname == NULL) { + localname = xmlStrdup(qname); + } + + + newnode = xmlNewChild(node, NULL, localname, value); + + if (nsuri != NULL) { + nsptr = xmlSearchNsByHref(node->doc, node, nsuri); + if (nsptr == NULL) { + nsptr = xmlNewNs(newnode, nsuri, prefix); + } + newnode->ns = nsptr; + } + + _node_as_zval(sxe, newnode, return_value, SXE_ITER_NONE, localname, prefix TSRMLS_CC); + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } +} +/* }}} */ + +/* {{{ proto void SimpleXMLElement::addAttribute(string qName, string value [,string ns]) + Add Attribute with optional namespace information */ +SXE_METHOD(addAttribute) +{ + php_sxe_object *sxe; + char *qname, *value = NULL, *nsuri = NULL; + int qname_len, value_len = 0, nsuri_len = 0; + xmlNodePtr node; + xmlAttrPtr attrp = NULL; + xmlNsPtr nsptr = NULL; + xmlChar *localname, *prefix = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss!s!", + &qname, &qname_len, &value, &value_len, &nsuri, &nsuri_len) == FAILURE) { + return; + } + + if (qname_len == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute name and value are required"); + return; + } + + sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); + GET_NODE(sxe, node); + + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (node->type != XML_ELEMENT_NODE) { + node = node->parent; + } + + if (node == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate parent Element"); + return; + } + + localname = xmlSplitQName2(qname, &prefix); + if (localname == NULL) { + localname = xmlStrdup(qname); + } + + attrp = xmlHasNsProp(node, localname, nsuri); + if (attrp != NULL && attrp->type != XML_ATTRIBUTE_DECL) { + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attribute already exists"); + return; + } + + if (nsuri != NULL) { + nsptr = xmlSearchNsByHref(node->doc, node, nsuri); + if (nsptr == NULL) { + nsptr = xmlNewNs(node, nsuri, prefix); + } + } + + attrp = xmlNewNsProp(node, nsptr, localname, value); + + xmlFree(localname); + if (prefix != NULL) { + xmlFree(prefix); + } +} +/* }}} */ + /* {{{ cast_object() */ static int cast_object(zval *object, int type, char *contents TSRMLS_DC) @@ -2118,6 +2241,8 @@ static zend_function_entry sxe_functions SXE_ME(getNamespaces, NULL, ZEND_ACC_PUBLIC) SXE_ME(getDocNamespaces, NULL, ZEND_ACC_PUBLIC) SXE_ME(getName, NULL, ZEND_ACC_PUBLIC) + SXE_ME(addChild, NULL, ZEND_ACC_PUBLIC) + SXE_ME(addAttribute, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} };