rrichards Tue Mar 7 15:22:48 2006 UTC Added files: (Branch: PHP_5_1) /php-src/ext/simplexml/tests 030.phpt 031.phpt
Modified files: /php-src/ext/simplexml simplexml.c /php-src/ext/simplexml/tests 027.phpt bug35785.phpt Log: - Synch with head
http://cvs.php.net/viewcvs.cgi/php-src/ext/simplexml/simplexml.c?r1=1.151.2.17&r2=1.151.2.18&diff_format=u Index: php-src/ext/simplexml/simplexml.c diff -u php-src/ext/simplexml/simplexml.c:1.151.2.17 php-src/ext/simplexml/simplexml.c:1.151.2.18 --- php-src/ext/simplexml/simplexml.c:1.151.2.17 Sun Mar 5 15:36:03 2006 +++ php-src/ext/simplexml/simplexml.c Tue Mar 7 15:22:48 2006 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: simplexml.c,v 1.151.2.17 2006/03/05 15:36:03 tony2001 Exp $ */ +/* $Id: simplexml.c,v 1.151.2.18 2006/03/07 15:22:48 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -632,6 +632,14 @@ xmlAttrPtr attr = NULL; int exists = 0; int test = 0; + zval tmp_zv; + + if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) { + tmp_zv = *member; + zval_copy_ctor(&tmp_zv); + member = &tmp_zv; + convert_to_string(member); + } sxe = php_sxe_fetch_object(object TSRMLS_CC); @@ -661,13 +669,28 @@ if (node) { if (attribs) { - while (attr) { - if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { - exists = 1; - break; + if (Z_TYPE_P(member) == IS_LONG) { + int nodendx = 0; + + while (attr && nodendx <= Z_LVAL_P(member)) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { + if (nodendx == Z_LVAL_P(member)) { + exists = 1; + break; + } + nodendx++; + } + attr = attr->next; } + } else { + while (attr) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { + exists = 1; + break; + } - attr = attr->next; + attr = attr->next; + } } } @@ -679,14 +702,6 @@ node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL); } else { - zval tmp_zv; - - if (Z_TYPE_P(member) != IS_STRING) { - tmp_zv = *member; - zval_copy_ctor(&tmp_zv); - member = &tmp_zv; - convert_to_string(member); - } node = node->children; while (node) { xmlNodePtr nnext; @@ -696,9 +711,6 @@ } node = nnext; } - if (member == &tmp_zv) { - zval_dtor(&tmp_zv); - } } if (node) { exists = 1; @@ -706,6 +718,10 @@ } } + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + return exists; } /* }}} */ @@ -733,12 +749,12 @@ 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) { + if (Z_TYPE_P(member) != IS_STRING && Z_TYPE_P(member) != IS_LONG) { tmp_zv = *member; zval_copy_ctor(&tmp_zv); member = &tmp_zv; @@ -748,13 +764,24 @@ sxe = php_sxe_fetch_object(object TSRMLS_CC); GET_NODE(sxe, node); + + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + attribs = 0; + elements = 1; + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + } + } + if (sxe->iter.type == SXE_ITER_ATTRLIST) { attribs = 1; elements = 0; node = php_sxe_get_first_node(sxe, node TSRMLS_CC); attr = (xmlAttrPtr)node; test = sxe->iter.name != NULL; - } else { + } else if (sxe->iter.type != SXE_ITER_CHILD) { node = php_sxe_get_first_node(sxe, node TSRMLS_CC); attr = node ? node->properties : NULL; test = 0; @@ -762,31 +789,58 @@ if (node) { if (attribs) { - while (attr) { - anext = attr->next; - if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { - xmlUnlinkNode((xmlNodePtr) attr); - php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC); - break; + if (Z_TYPE_P(member) == IS_LONG) { + int nodendx = 0; + + while (attr && nodendx <= Z_LVAL_P(member)) { + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { + if (nodendx == Z_LVAL_P(member)) { + xmlUnlinkNode((xmlNodePtr) attr); + php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC); + break; + } + nodendx++; + } + attr = attr->next; + } + } else { + while (attr) { + anext = attr->next; + if ((!test || !xmlStrcmp(attr->name, sxe->iter.name)) && !xmlStrcmp(attr->name, Z_STRVAL_P(member)) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { + xmlUnlinkNode((xmlNodePtr) attr); + php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC); + break; + } + attr = anext; } - attr = anext; } } if (elements) { - node = node->children; - while (node) { - nnext = node->next; - - SKIP_TEXT(node); - - if (!xmlStrcmp(node->name, Z_STRVAL_P(member))) { + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL); + if (node) { xmlUnlinkNode(node); php_libxml_node_free_resource(node TSRMLS_CC); } + } else { + node = node->children; + while (node) { + nnext = node->next; + + SKIP_TEXT(node); + + if (!xmlStrcmp(node->name, Z_STRVAL_P(member))) { + xmlUnlinkNode(node); + php_libxml_node_free_resource(node TSRMLS_CC); + } next_iter: - node = nnext; + node = nnext; + } } } } @@ -1356,6 +1410,129 @@ } /* }}} */ +/* {{{ 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) @@ -2059,6 +2236,8 @@ 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} }; @@ -2111,7 +2290,7 @@ { php_info_print_table_start(); php_info_print_table_header(2, "Simplexml support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.151.2.17 $"); + php_info_print_table_row(2, "Revision", "$Revision: 1.151.2.18 $"); php_info_print_table_row(2, "Schema support", #ifdef LIBXML_SCHEMAS_ENABLED "enabled"); http://cvs.php.net/viewcvs.cgi/php-src/ext/simplexml/tests/027.phpt?r1=1.1.2.2&r2=1.1.2.3&diff_format=u Index: php-src/ext/simplexml/tests/027.phpt diff -u php-src/ext/simplexml/tests/027.phpt:1.1.2.2 php-src/ext/simplexml/tests/027.phpt:1.1.2.3 --- php-src/ext/simplexml/tests/027.phpt:1.1.2.2 Sun Feb 26 23:14:45 2006 +++ php-src/ext/simplexml/tests/027.phpt Tue Mar 7 15:22:48 2006 @@ -61,7 +61,7 @@ </person> </people> -Warning: main(): Cannot add element person number 3 when only 2 such elements exist in %sext/simplexml/tests/027.php on line %d +Warning: main(): Cannot add element person number 3 when only 2 such elements exist in %s027.php on line %d <people> <person gender="female">Jane </person> @@ -71,4 +71,4 @@ </person> </people> -Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in %sext/simplexml/tests/027.php on line %d +Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in %s027.php on line %d http://cvs.php.net/viewcvs.cgi/php-src/ext/simplexml/tests/bug35785.phpt?r1=1.1.2.4&r2=1.1.2.5&diff_format=u Index: php-src/ext/simplexml/tests/bug35785.phpt diff -u php-src/ext/simplexml/tests/bug35785.phpt:1.1.2.4 php-src/ext/simplexml/tests/bug35785.phpt:1.1.2.5 --- php-src/ext/simplexml/tests/bug35785.phpt:1.1.2.4 Sun Feb 26 23:14:45 2006 +++ php-src/ext/simplexml/tests/bug35785.phpt Tue Mar 7 15:22:48 2006 @@ -23,4 +23,4 @@ ===FAIL=== int(0) -Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in %sext/simplexml/tests/bug35785.php on line %d +Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference in %sbug35785.php on line %d http://cvs.php.net/viewcvs.cgi/php-src/ext/simplexml/tests/030.phpt?view=markup&rev=1.1 Index: php-src/ext/simplexml/tests/030.phpt +++ php-src/ext/simplexml/tests/030.phpt --TEST-- SimpleXML: isset and unset by offset --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); echo $sxe->child1[0]."\n"; echo $sxe->child1[1]."\n\n"; var_dump(isset($sxe->child1[1])); unset($sxe->child1[1]); var_dump(isset($sxe->child1[1])); echo "\n"; $atts = $sxe->attributes("urn::test"); var_dump(isset($atts[0])); unset($atts[0]); var_dump(isset($atts[0])); var_dump(isset($atts[TRUE])); ?> ===DONE=== --EXPECT-- test test 2 bool(true) bool(false) bool(true) bool(false) bool(false) ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/simplexml/tests/031.phpt?view=markup&rev=1.1 Index: php-src/ext/simplexml/tests/031.phpt +++ php-src/ext/simplexml/tests/031.phpt --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===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php