diff options
author | Rob Richards <rrichards@php.net> | 2006-03-06 20:16:03 +0000 |
---|---|---|
committer | Rob Richards <rrichards@php.net> | 2006-03-06 20:16:03 +0000 |
commit | 032edbfb9288baf45190ab690b9bacb73445f978 (patch) | |
tree | 85e7f7c8e911bcf5dcb045b0c4495a75057c696c | |
parent | edd7d2a1df68ca4a382d83954bd8e8bae430a5ac (diff) | |
download | php-git-032edbfb9288baf45190ab690b9bacb73445f978.tar.gz |
implement addChild() and addAttribute() methods
add test
-rw-r--r-- | ext/simplexml/simplexml.c | 129 | ||||
-rw-r--r-- | ext/simplexml/tests/031.phpt | 68 |
2 files changed, 195 insertions, 2 deletions
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 56cd5ddadc..d8708e04b3 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -751,10 +751,10 @@ static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements, php_sxe_object *sxe; xmlNodePtr node; xmlNodePtr nnext; - xmlAttrPtr attr; + xmlAttrPtr attr = NULL; xmlAttrPtr anext; zval tmp_zv; - int test; + int test = 0; if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) { tmp_zv = *member; @@ -1411,6 +1411,129 @@ SXE_METHOD(attributes) } /* }}} */ +/* {{{ proto void 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 || value_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) @@ -2126,6 +2249,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} }; diff --git a/ext/simplexml/tests/031.phpt b/ext/simplexml/tests/031.phpt new file mode 100644 index 0000000000..3d6a57127a --- /dev/null +++ b/ext/simplexml/tests/031.phpt @@ -0,0 +1,68 @@ +--TEST-- +SimpleXML: addChild and addAttribute +--SKIPIF-- +<?php if (!extension_loaded("simplexml")) print "skip"; ?> +--FILE-- +<?php +$xml =<<<EOF +<root s:att1="b" att1="a" + xmlns:s="urn::test" xmlns:t="urn::test-t"> + <child1>test</child1> + <child1>test 2</child1> + <s:child3 /> +</root> +EOF; + +$sxe = simplexml_load_string($xml); + +/* Add new attribute in a new namespace */ +$sxe->addAttribute('v:att11', 'xxx', 'urn::test-v'); + +/* Try to add attribute again -> display warning as method is for new Attr only */ +$sxe->addAttribute('v:att11', 'xxx', 'urn::test-v'); + +/* Add new attribute w/o namespace */ +$sxe->addAttribute('att2', 'no-ns'); + +$d = $sxe->attributes(); +/* Try to add element to attribute -> display warning and do not add */ +$d->addChild('m:test', 'myval', 'urn::test'); + + +/* Test adding elements in various configurations */ +$sxe->addChild('m:test1', 'myval', 'urn::test'); + +/* New namespace test */ +$n = $sxe->addChild('m:test2', 'myval', 'urn::testnew'); + +$sxe->addChild('test3', 'myval', 'urn::testnew'); +$sxe->addChild('test4', 'myval'); + +/* Does not add prefix here although name is valid (but discouraged) - change behavior? */ +$sxe->addChild('s:test5', 'myval'); + +echo $sxe->asXML(); +?> +===DONE=== +--EXPECTF-- +Warning: SimpleXMLElement::addAttribute(): Attribute already exists in %s031.php on line %d + +Warning: SimpleXMLElement::addChild(): Cannot add element to attributes in %s031.php on line %d +<?xml version="1.0"?> +<root xmlns:s="urn::test" xmlns:t="urn::test-t" xmlns:v="urn::test-v" s:att1="b" att1="a" v:att11="xxx" att2="no-ns"> + <child1>test</child1> + <child1>test 2</child1> + <s:child3/> +<s:test1>myval</s:test1><m:test2 xmlns:m="urn::testnew">myval</m:test2><test3 xmlns="urn::testnew">myval</test3><test4>myval</test4><test5>myval</test5></root> +===DONE=== +--UEXPECTF-- +unicode(3) "Joe" +int(3) +int(0) +unicode(4) "John" +int(3) +int(1) +unicode(4) "Jane" +int(3) +int(0) +===DONE===
\ No newline at end of file |