]> granicus.if.org Git - php/commitdiff
- Added ability to add elements by index if such elements already exist
authorMarcus Boerger <helly@php.net>
Sat, 25 Feb 2006 23:41:06 +0000 (23:41 +0000)
committerMarcus Boerger <helly@php.net>
Sat, 25 Feb 2006 23:41:06 +0000 (23:41 +0000)
- Added SimpleXMLElement::getName() to access the node name
# This allows to retrieve the name of the root element which is otherwise
# only available by converting the sxe object into a dom object.

ext/simplexml/simplexml.c
ext/simplexml/tests/026.phpt [new file with mode: 0755]
ext/simplexml/tests/027.phpt [new file with mode: 0755]

index 276bacb9fc3c043b6ceea6f3925aeaaaea824d75..65160690118f010b959d2c401b08a1229b65fbe3 100644 (file)
@@ -130,10 +130,10 @@ static inline int match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name)
 }
 /* }}} */
 
-static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node) /* {{{ */
+static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node, long *cnt) /* {{{ */
 {
        long nodendx = 0;
-
+       
        if (sxe->iter.type == SXE_ITER_NONE) {
                return NULL;
        }
@@ -151,6 +151,10 @@ static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xm
 next_iter:
                node = node->next;
        }
+       
+       if (cnt) {
+               *cnt = nodendx;
+       }
 
        return node;
 }
@@ -303,7 +307,7 @@ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements,
                                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);
+                               node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
                                if (node) {
                                        _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix TSRMLS_CC);
                                }
@@ -397,6 +401,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
        int             is_attr = 0;
        int                             nodendx = 0;
        int             test = 0;
+       long            cnt;
        zval            tmp_zv, trim_zv;
 
        if (!member) {
@@ -482,7 +487,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
 
                if (elements) {
                        if (Z_TYPE_P(member) == IS_LONG) {
-                               newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node);
+                               newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
                                if (newnode) {
                                        ++counter;
                                }
@@ -513,8 +518,15 @@ next_iter:
                        change_node_zval(newnode, value TSRMLS_CC);
                } else if (counter > 1) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)");
-               } else if (elements && !node) {
-                       xmlNewChild(mynode, mynode->ns, name, Z_STRVAL_P(value));       
+               } else if (elements) {
+                       if (!node) {
+                               xmlNewTextChild(mynode, mynode->ns, name, Z_STRVAL_P(value));
+                       } else if (Z_TYPE_P(member) == IS_LONG) {
+                               if (cnt < Z_LVAL_P(member)) {
+                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only %ld such elements exist", mynode->name, Z_LVAL_P(member), cnt);
+                               }
+                               xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, Z_STRVAL_P(value));
+                       }
                } else {
                        if (attribs) {
                                switch (Z_TYPE_P(value)) {
@@ -612,7 +624,7 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend
                                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);
+                               node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
                        }
                        else {
                                zval tmp_zv;
@@ -1221,7 +1233,7 @@ SXE_METHOD(getDocNamespaces)
 }
 /* }}} */
 
-/* {{{ proto object SimpleXMLElement::children()
+/* {{{ proto object SimpleXMLElement::children([string ns])
    Finds children of given node */
 SXE_METHOD(children)
 {
@@ -1248,6 +1260,23 @@ SXE_METHOD(children)
 }
 /* }}} */
 
+/* {{{ proto object SimpleXMLElement::getName()
+   Finds children of given node */
+SXE_METHOD(getName)
+{
+       php_sxe_object *sxe;
+       xmlNodePtr      node;
+       int             namelen;
+
+       sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+
+       GET_NODE(sxe, node);
+       
+       namelen = xmlStrlen(node->name);
+       RETURN_STRINGL((char*)node->name, namelen, 1);
+}
+/* }}} */
+
 /* {{{ proto array SimpleXMLElement::attributes([string ns])
    Identifies an element's attributes */
 SXE_METHOD(attributes)
@@ -1985,6 +2014,7 @@ static zend_function_entry sxe_functions[] = {
        SXE_ME(children,               NULL, ZEND_ACC_PUBLIC)
        SXE_ME(getNamespaces,          NULL, ZEND_ACC_PUBLIC)
        SXE_ME(getDocNamespaces,       NULL, ZEND_ACC_PUBLIC)
+       SXE_ME(getName,                NULL, ZEND_ACC_PUBLIC)
        {NULL, NULL, NULL}
 };
 
diff --git a/ext/simplexml/tests/026.phpt b/ext/simplexml/tests/026.phpt
new file mode 100755 (executable)
index 0000000..d6de94b
--- /dev/null
@@ -0,0 +1,40 @@
+--TEST--
+SimpleXML: getName()
+--SKIPIF--
+<?php if (!extension_loaded("simplexml")) print "skip"; ?>
+--FILE--
+<?php 
+$xml =<<<EOF
+<people>
+  <person>Jane</person>
+</people>
+EOF;
+
+function traverse_xml($xml, $pad = '')
+{
+  $name = $xml->getName();
+  echo "$pad<$name";
+  foreach($xml->attributes() as $attr => $value)
+  {
+    echo " $attr=\"$value\"";
+  }
+  echo ">" . trim($xml) . "\n";
+  foreach($xml->children() as $node)
+  {
+    traverse_xml($node, $pad.'  ');
+  }
+  echo $pad."</$name>\n";
+}
+
+
+$people = simplexml_load_string($xml);
+traverse_xml($people);
+
+?>
+===DONE===
+--EXPECTF--
+<people>
+  <person>Jane
+  </person>
+</people>
+===DONE===
diff --git a/ext/simplexml/tests/027.phpt b/ext/simplexml/tests/027.phpt
new file mode 100755 (executable)
index 0000000..0c8f4e2
--- /dev/null
@@ -0,0 +1,74 @@
+--TEST--
+SimpleXML: Adding an elements
+--SKIPIF--
+<?php if (!extension_loaded("simplexml")) print "skip"; ?>
+--FILE--
+<?php 
+$xml =<<<EOF
+<people></people>
+EOF;
+
+function traverse_xml($xml, $pad = '')
+{
+  $name = $xml->getName();
+  echo "$pad<$name";
+  foreach($xml->attributes() as $attr => $value)
+  {
+    echo " $attr=\"$value\"";
+  }
+  echo ">" . trim($xml) . "\n";
+  foreach($xml->children() as $node)
+  {
+    traverse_xml($node, $pad.'  ');
+  }
+  echo $pad."</$name>\n";
+}
+
+
+$people = simplexml_load_string($xml);
+traverse_xml($people);
+$people->person = 'Joe';
+$people->person['gender'] = 'male';
+traverse_xml($people);
+$people->person = 'Jane';
+traverse_xml($people);
+$people->person['gender'] = 'female';
+$people->person[1] = 'Joe';
+$people->person[1]['gender'] = 'male';
+traverse_xml($people);
+$people->person[3] = 'Minni-me';
+$people->person[2]['gender'] = 'male';
+traverse_xml($people);
+$people->person[3]['gender'] = 'error';
+
+?>
+===DONE===
+--EXPECTF--
+<people>
+</people>
+<people>
+  <person gender="male">Joe
+  </person>
+</people>
+<people>
+  <person gender="male">Jane
+  </person>
+</people>
+<people>
+  <person gender="female">Jane
+  </person>
+  <person gender="male">Joe
+  </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
+<people>
+  <person gender="female">Jane
+  </person>
+  <person gender="male">Joe
+  </person>
+  <person gender="male">Minni-me
+  </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