rrichards Mon Mar 6 20:16:03 2006 UTC
Added files:
/php-src/ext/simplexml/tests 031.phpt
Modified files:
/php-src/ext/simplexml simplexml.c
Log:
implement addChild() and addAttribute() methods
add test
http://cvs.php.net/viewcvs.cgi/php-src/ext/simplexml/simplexml.c?r1=1.199&r2=1.200&diff_format=u
Index: php-src/ext/simplexml/simplexml.c
diff -u php-src/ext/simplexml/simplexml.c:1.199
php-src/ext/simplexml/simplexml.c:1.200
--- php-src/ext/simplexml/simplexml.c:1.199 Sun Mar 5 15:58:09 2006
+++ php-src/ext/simplexml/simplexml.c Mon Mar 6 20:16:03 2006
@@ -18,7 +18,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: simplexml.c,v 1.199 2006/03/05 15:58:09 tony2001 Exp $ */
+/* $Id: simplexml.c,v 1.200 2006/03/06 20:16:03 rrichards Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -751,10 +751,10 @@
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 @@
}
/* }}} */
+/* {{{ 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 @@
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}
};
@@ -2178,7 +2303,7 @@
{
php_info_print_table_start();
php_info_print_table_header(2, "Simplexml support", "enabled");
- php_info_print_table_row(2, "Revision", "$Revision: 1.199 $");
+ php_info_print_table_row(2, "Revision", "$Revision: 1.200 $");
php_info_print_table_row(2, "Schema support",
#ifdef LIBXML_SCHEMAS_ENABLED
"enabled");
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