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

Reply via email to