summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2003-10-29 12:06:52 +0000
committerMarcus Boerger <helly@php.net>2003-10-29 12:06:52 +0000
commit6b57bb16752e475166a43ce0a38b96b7241b1236 (patch)
treebd5d22ba6b9e901c3ec8409db061d44c49508b00
parentc26303c7895473c54d926b03cb6437073c26cd6f (diff)
downloadphp-git-6b57bb16752e475166a43ce0a38b96b7241b1236.tar.gz
Add simplexml array handlers that allow to explicitly work with attributes.
-rw-r--r--ext/simplexml/simplexml.c239
-rwxr-xr-xext/simplexml/tests/007.phpt27
2 files changed, 177 insertions, 89 deletions
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index 7fc199d41d..b2ae27872b 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -13,6 +13,7 @@
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Sterling Hughes <sterling@php.net> |
+ | Marcus Boerger <helly@php.net> |
+----------------------------------------------------------------------+
*/
@@ -115,10 +116,10 @@ match_ns(php_sxe_object *sxe, xmlNodePtr node, xmlChar *name)
}
/* }}} */
-/* {{{ sxe_property_read()
+/* {{{ sxe_prop_dim_read()
*/
static zval *
-sxe_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC)
+sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, zend_bool silent TSRMLS_DC)
{
zval *return_value;
zval *value = NULL;
@@ -139,54 +140,58 @@ sxe_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC)
GET_NODE(sxe, node);
if (node) {
- attr = node->properties;
- while (attr) {
- if (!xmlStrcmp(attr->name, name)) {
- APPEND_PREV_ELEMENT(counter, value);
-
- MAKE_STD_ZVAL(value);
- contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1);
- ZVAL_STRING(value, contents, 1);
- if (contents) {
- xmlFree(contents);
+ if (attribs) {
+ attr = node->properties;
+ while (attr) {
+ if (!xmlStrcmp(attr->name, name)) {
+ APPEND_PREV_ELEMENT(counter, value);
+
+ MAKE_STD_ZVAL(value);
+ contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, attr->children, 1);
+ ZVAL_STRING(value, contents, 1);
+ if (contents) {
+ xmlFree(contents);
+ }
+ APPEND_CUR_ELEMENT(counter, value);
}
- APPEND_CUR_ELEMENT(counter, value);
+ attr = attr->next;
}
- attr = attr->next;
}
- if (!sxe->node) {
- php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL TSRMLS_CC);
- }
- node = node->children;
-
- while (node) {
- SKIP_TEXT(node);
-
- do if (node->ns) {
- if (node->parent->ns) {
- if (!xmlStrcmp(node->ns->href, node->parent->ns->href)) {
- break;
- }
- }
+ if (elements) {
+ if (!sxe->node) {
+ php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL TSRMLS_CC);
+ }
+ node = node->children;
+
+ while (node) {
+ SKIP_TEXT(node);
- if (match_ns(sxe, node, name)) {
+ do if (node->ns) {
+ if (node->parent->ns) {
+ if (!xmlStrcmp(node->ns->href, node->parent->ns->href)) {
+ break;
+ }
+ }
+
+ if (match_ns(sxe, node, name)) {
+ MAKE_STD_ZVAL(value);
+ _node_as_zval(sxe, node->parent, value TSRMLS_CC);
+ APPEND_CUR_ELEMENT(counter, value);
+ goto next_iter;
+ }
+ } while (0);
+
+ if (!xmlStrcmp(node->name, name)) {
+ APPEND_PREV_ELEMENT(counter, value);
MAKE_STD_ZVAL(value);
- _node_as_zval(sxe, node->parent, value TSRMLS_CC);
+ _node_as_zval(sxe, node, value TSRMLS_CC);
APPEND_CUR_ELEMENT(counter, value);
- goto next_iter;
}
- } while (0);
-
- if (!xmlStrcmp(node->name, name)) {
- APPEND_PREV_ELEMENT(counter, value);
- MAKE_STD_ZVAL(value);
- _node_as_zval(sxe, node, value TSRMLS_CC);
- APPEND_CUR_ELEMENT(counter, value);
- }
-
+
next_iter:
- node = node->next;
+ node = node->next;
+ }
}
/* Only one value found */
@@ -205,6 +210,24 @@ next_iter:
}
/* }}} */
+/* {{{ sxe_property_read()
+ */
+static zval *
+sxe_property_read(zval *object, zval *member, zend_bool silent TSRMLS_DC)
+{
+ return sxe_prop_dim_read(object, member, 1, 1, silent TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ sxe_dimension_read()
+ */
+static zval *sxe_dimension_read(zval *object, zval *offset TSRMLS_DC)
+{
+ convert_to_string_ex(&offset);
+ return sxe_prop_dim_read(object, offset, 0, 1, 0 TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ change_node_zval()
*/
static void
@@ -228,15 +251,14 @@ change_node_zval(xmlNodePtr node, zval *value)
/* {{{ sxe_property_write()
*/
-static void
-sxe_property_write(zval *object, zval *member, zval *value TSRMLS_DC)
+static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool elements, zend_bool attribs TSRMLS_DC)
{
php_sxe_object *sxe;
char *name;
xmlNodePtr node;
xmlNodePtr newnode = NULL;
xmlNodePtr tempnode;
- xmlAttrPtr attr;
+ xmlAttrPtr attr = NULL;
int counter = 0;
int is_attr = 0;
@@ -246,27 +268,31 @@ sxe_property_write(zval *object, zval *member, zval *value TSRMLS_DC)
GET_NODE(sxe, node);
if (node) {
- attr = node->properties;
- while (attr) {
- if (!xmlStrcmp(attr->name, name)) {
- is_attr = 1;
- ++counter;
- break;
+ if (attribs) {
+ attr = node->properties;
+ while (attr) {
+ if (!xmlStrcmp(attr->name, name)) {
+ is_attr = 1;
+ ++counter;
+ break;
+ }
+
+ attr = attr->next;
}
-
- attr = attr->next;
}
- node = node->children;
- while (node) {
- SKIP_TEXT(node);
- if (!xmlStrcmp(node->name, name)) {
- newnode = node;
- ++counter;
- }
-
+ if (elements) {
+ node = node->children;
+ while (node) {
+ SKIP_TEXT(node);
+ if (!xmlStrcmp(node->name, name)) {
+ newnode = node;
+ ++counter;
+ }
+
next_iter:
- node = node->next;
+ node = node->next;
+ }
}
if (counter == 1) {
@@ -280,11 +306,30 @@ next_iter:
change_node_zval(newnode, value);
} else if (counter > 1) {
php_error(E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)\n");
+ } else {
+ php_error(E_WARNING, "Cannot create new atrribute\n");
}
}
}
/* }}} */
+/* {{{ sxe_property_write()
+ */
+static void sxe_property_write(zval *object, zval *member, zval *value TSRMLS_DC)
+{
+ sxe_prop_dim_write(object, member, value, 1, 1 TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ sxe_dimension_write()
+ */
+static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_DC)
+{
+ convert_to_string_ex(&offset);
+ sxe_prop_dim_write(object, offset, value, 0, 1 TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ sxe_property_exists()
*/
static int
@@ -327,10 +372,9 @@ next_iter:
}
/* }}} */
-/* {{{ sxe_property_delete()
+/* {{{ sxe_prop_dim_delete()
*/
-static void
-sxe_property_delete(zval *object, zval *member TSRMLS_DC)
+static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements, zend_bool attribs TSRMLS_DC)
{
php_sxe_object *sxe;
xmlNodePtr node;
@@ -343,34 +387,56 @@ sxe_property_delete(zval *object, zval *member TSRMLS_DC)
GET_NODE(sxe, node);
if (node) {
- attr = node->properties;
- while (attr) {
- anext = attr->next;
- if (!xmlStrcmp(attr->name, Z_STRVAL_P(member))) {
- xmlUnlinkNode((xmlNodePtr) attr);
- xmlFreeProp(attr);
+ if (attribs) {
+ attr = node->properties;
+ while (attr) {
+ anext = attr->next;
+ if (!xmlStrcmp(attr->name, Z_STRVAL_P(member))) {
+ xmlUnlinkNode((xmlNodePtr) attr);
+ xmlFreeProp(attr);
+ }
+ attr = anext;
}
- attr = anext;
}
-
- node = node->children;
- while (node) {
- nnext = node->next;
- SKIP_TEXT(node);
-
- if (!xmlStrcmp(node->name, Z_STRVAL_P(member))) {
- xmlUnlinkNode(node);
- xmlFreeNode(node);
- }
+ if (elements) {
+ node = node->children;
+ while (node) {
+ nnext = node->next;
+
+ SKIP_TEXT(node);
+
+ if (!xmlStrcmp(node->name, Z_STRVAL_P(member))) {
+ xmlUnlinkNode(node);
+ xmlFreeNode(node);
+ }
next_iter:
- node = nnext;
+ node = nnext;
+ }
}
}
}
/* }}} */
+/* {{{ sxe_property_delete()
+ */
+static void
+sxe_property_delete(zval *object, zval *member TSRMLS_DC)
+{
+ sxe_prop_dim_delete(object, member, 1, 1 TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ sxe_dimension_unset()
+ */
+static void sxe_dimension_delete(zval *object, zval *offset TSRMLS_DC)
+{
+ convert_to_string_ex(&offset);
+ sxe_prop_dim_delete(object, offset, 1, 1 TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ _get_base_node_value()
*/
static void
@@ -867,14 +933,14 @@ static zend_object_handlers sxe_object_handlers = {
ZEND_OBJECTS_STORE_HANDLERS,
sxe_property_read,
sxe_property_write,
- NULL,
- NULL,
+ sxe_dimension_read,
+ sxe_dimension_write,
NULL,
sxe_object_get,
sxe_object_set,
sxe_property_exists,
sxe_property_delete,
- NULL,
+ sxe_dimension_delete,
sxe_properties_get,
sxe_method_get,
sxe_call_method,
@@ -1096,13 +1162,12 @@ static void php_sxe_iterator_current(php_sxe_iterator *iterator TSRMLS_DC)
_get_base_node_value(iterator->sxe, iterator->node, &iterator->data TSRMLS_CC);
- iterator->node->name = (char *) iterator->node->name;
if (!iterator->node->name) {
iterator->name = "CDATA";
iterator->namelen = sizeof("CDATA");
} else {
iterator->namelen = xmlStrlen(iterator->node->name)+1;
- iterator->name = iterator->node->name;
+ iterator->name = (char *) iterator->node->name;
}
break;
next_iter:
diff --git a/ext/simplexml/tests/007.phpt b/ext/simplexml/tests/007.phpt
index 0d1f14e4af..023d7d3c62 100755
--- a/ext/simplexml/tests/007.phpt
+++ b/ext/simplexml/tests/007.phpt
@@ -7,13 +7,36 @@ SimpleXML and attributes
$sxe = simplexml_load_file(dirname(__FILE__).'/sxe.xml');
+echo "===Property===\n";
var_dump($sxe->id);
var_dump($sxe->elem1->attr1);
-
-echo "===Done===\n";
+echo "===Array===\n";
+var_dump($sxe['id']);
+var_dump($sxe->elem1['attr1']);
+echo "===Set===\n";
+$sxe['id'] = "Changed1";
+var_dump($sxe['id']);
+$sxe->elem1['attr1'] = 12;
+var_dump($sxe->elem1['attr1']);
+echo "===Unset===\n";
+unset($sxe['id']);
+var_dump($sxe['id']);
+unset($sxe->elem1['attr1']);
+var_dump($sxe->elem1['attr1']);
?>
+===Done===
--EXPECT--
+===Property===
+string(5) "elem1"
+string(5) "first"
+===Array===
string(5) "elem1"
string(5) "first"
+===Set===
+string(8) "Changed1"
+string(2) "12"
+===Unset===
+NULL
+NULL
===Done===