summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Richards <rrichards@php.net>2004-01-13 21:28:41 +0000
committerRob Richards <rrichards@php.net>2004-01-13 21:28:41 +0000
commitad47abf0f6d838cc508dfb115ca5e3fff9d621fb (patch)
treefc72b03dfa26ff8e53213e538966e5667763e794
parent5b59254761be32f82aa404c3ff3d758243b3434e (diff)
downloadphp-git-ad47abf0f6d838cc508dfb115ca5e3fff9d621fb.tar.gz
add support for $foo["a:bar"]
fix xsearch to only return values for text,element and attribute nodes fix getChildren and return array remove most methods update test
-rw-r--r--ext/simplexml/simplexml.c230
-rw-r--r--ext/simplexml/tests/017.phpt4
2 files changed, 89 insertions, 145 deletions
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index f624522c23..0c4f478a9c 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -158,9 +158,14 @@ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements,
if (node) {
if (attribs) {
+ xmlChar *localname, *prefix=NULL;
+ localname = xmlSplitQName2(name, &prefix);
+ if (localname == NULL) {
+ localname = (xmlChar *)name;
+ }
attr = node->properties;
while (attr) {
- if (!xmlStrcmp(attr->name, name)) {
+ if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || (attr->ns && !xmlStrcmp(attr->ns->prefix, prefix)))) {
APPEND_PREV_ELEMENT(counter, value);
MAKE_STD_ZVAL(value);
@@ -173,6 +178,12 @@ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements,
}
attr = attr->next;
}
+ if (prefix) {
+ xmlFree(prefix);
+ if (localname) {
+ xmlFree(localname);
+ }
+ }
}
if (elements) {
@@ -319,9 +330,14 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
if (node) {
if (attribs) {
+ xmlChar *localname, *prefix=NULL;
+ localname = xmlSplitQName2(name, &prefix);
+ if (localname == NULL) {
+ localname = (xmlChar *)name;
+ }
attr = node->properties;
while (attr) {
- if (!xmlStrcmp(attr->name, name)) {
+ if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || (attr->ns && !xmlStrcmp(attr->ns->prefix, prefix)))) {
is_attr = 1;
++counter;
break;
@@ -329,6 +345,12 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
attr = attr->next;
}
+ if (prefix) {
+ xmlFree(prefix);
+ if (localname) {
+ xmlFree(localname);
+ }
+ }
}
if (elements) {
@@ -402,6 +424,7 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend
char *name;
xmlNodePtr node;
xmlAttrPtr attr = NULL;
+ int exists = 0;
sxe = php_sxe_fetch_object(object TSRMLS_CC);
name = Z_STRVAL_P(member);
@@ -410,14 +433,26 @@ static int sxe_prop_dim_exists(zval *object, zval *member, int check_empty, zend
if (node) {
if (attribs) {
+ xmlChar *localname, *prefix=NULL;
+ localname = xmlSplitQName2(name, &prefix);
+ if (localname == NULL) {
+ localname = (xmlChar *)name;
+ }
attr = node->properties;
while (attr) {
- if (!xmlStrcmp(attr->name, name)) {
- return 1;
+ if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || (attr->ns && !xmlStrcmp(attr->ns->prefix, prefix)))) {
+ exists = 1;
+ break;
}
attr = attr->next;
}
+ if (prefix) {
+ xmlFree(prefix);
+ if (localname) {
+ xmlFree(localname);
+ }
+ }
}
if (elements) {
@@ -435,7 +470,7 @@ next_iter:
}
}
- return 0;
+ return exists;
}
/* }}} */
@@ -479,15 +514,27 @@ static void sxe_prop_dim_delete(zval *object, zval *member, zend_bool elements,
if (node) {
if (attribs) {
+
+ xmlChar *localname, *prefix=NULL;
+ localname = xmlSplitQName2(Z_STRVAL_P(member), &prefix);
+ if (localname == NULL) {
+ localname = (xmlChar *)Z_STRVAL_P(member);
+ }
attr = node->properties;
while (attr) {
anext = attr->next;
- if (!xmlStrcmp(attr->name, Z_STRVAL_P(member))) {
+ if (!xmlStrcmp(attr->name, localname) && (prefix==NULL || (attr->ns && !xmlStrcmp(attr->ns->prefix, prefix)))) {
xmlUnlinkNode((xmlNodePtr) attr);
php_libxml_node_free_resource((xmlNodePtr) attr TSRMLS_CC);
}
attr = anext;
}
+ if (prefix) {
+ xmlFree(prefix);
+ if (localname) {
+ xmlFree(localname);
+ }
+ }
}
if (elements) {
@@ -687,6 +734,7 @@ SXE_METHOD(xsearch)
xmlNsPtr *ns = NULL;
xmlXPathObjectPtr retval;
xmlNodeSetPtr result;
+ xmlNodePtr nodeptr;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &query, &query_len) == FAILURE) {
return;
@@ -740,18 +788,22 @@ SXE_METHOD(xsearch)
array_init(return_value);
for (i = 0; i < result->nodeNr; ++i) {
- MAKE_STD_ZVAL(value);
- /**
- * Detect the case where the last selector is text(), simplexml
- * always accesses the text() child by default, therefore we assign
- * to the parent node.
- */
- if (result->nodeTab[i]->type == XML_TEXT_NODE) {
- _node_as_zval(sxe, result->nodeTab[i]->parent, value TSRMLS_CC);
- } else {
- _node_as_zval(sxe, result->nodeTab[i], value TSRMLS_CC);
+ nodeptr = result->nodeTab[i];
+ if (nodeptr->type == XML_TEXT_NODE || nodeptr->type == XML_ELEMENT_NODE || nodeptr->type == XML_ATTRIBUTE_NODE) {
+ MAKE_STD_ZVAL(value);
+ /**
+ * Detect the case where the last selector is text(), simplexml
+ * always accesses the text() child by default, therefore we assign
+ * to the parent node.
+ */
+ if (nodeptr->type == XML_TEXT_NODE) {
+ _node_as_zval(sxe, nodeptr->parent, value TSRMLS_CC);
+ } else {
+ _node_as_zval(sxe, nodeptr, value TSRMLS_CC);
+ }
+
+ add_next_index_zval(return_value, value);
}
- add_next_index_zval(return_value, value);
}
xmlXPathFreeObject(retval);
@@ -912,31 +964,6 @@ SXE_METHOD(to_xml_file)
}
/* }}} */
-/* {{{ simplexml_count()
- */
-SXE_METHOD(count)
-{
- char *name;
- int name_len;
- HashTable *subnodes;
- zval **data_ptr;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
- return;
- }
- subnodes = sxe_properties_get(getThis() TSRMLS_CC);
- if (zend_hash_find(subnodes, name, name_len+1, (void **) &data_ptr) == SUCCESS) {
- if (Z_TYPE_PP(data_ptr) == IS_ARRAY) {
- RETURN_LONG(zend_hash_num_elements(Z_ARRVAL_PP(data_ptr)));
- } else {
- RETURN_LONG(1);
- }
- } else {
- RETURN_LONG(0);
- }
-}
-/* }}} */
-
/* {{{ simplexml_attributes()
*/
SXE_METHOD(attributes)
@@ -1307,14 +1334,6 @@ static void php_sxe_iterator_current(php_sxe_object *sxe TSRMLS_DC)
SKIP_TEXT(node);
- do if (node->ns) {
- if (node->parent->ns) {
- if (!xmlStrcmp(node->ns->href, node->parent->ns->href)) {
- break;
- }
- }
- } while (0);
-
if (!sxe->iter.node->name) {
goto next_iter;
} else {
@@ -1393,103 +1412,35 @@ static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC)
php_sxe_iterator_current(iterator->sxe TSRMLS_CC);
}
-/* {{{ rewind()
- */
-SXE_METHOD(rewind)
-{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
- GET_NODE(sxe, sxe->iter.node);
- if (sxe->iter.node) {
- sxe->iter.node = sxe->iter.node->children;
- }
- php_sxe_iterator_current(sxe TSRMLS_CC);
-}
-/* }}} */
-
-/* {{{ hasMore()
- */
-SXE_METHOD(hasMore)
-{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
-
- RETURN_BOOL(sxe->iter.node);
-}
-/* }}} */
-
-/* {{{ curent()
- */
-SXE_METHOD(current)
-{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
-
- RETURN_ZVAL(sxe->iter.data, 1, 0);
-}
-/* }}} */
-
-/* {{{ key()
- */
-SXE_METHOD(key)
-{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
-
- RETURN_STRINGL(sxe->iter.name, sxe->iter.namelen-1, 1);
-}
-/* }}} */
-
-/* {{{ next()
+/* {{{ getChildren()
*/
-SXE_METHOD(next)
+SXE_METHOD(getChildren)
{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+ php_sxe_object *sxe;
+ xmlNodePtr node;
+ xmlNodePtr child;
+ zval *value = NULL;
- if (sxe->iter.node) {
- sxe->iter.node = sxe->iter.node->next;
+ if (ZEND_NUM_ARGS() != 0) {
+ RETURN_FALSE;
}
- php_sxe_iterator_current(sxe TSRMLS_CC);
-}
-/* }}} */
-/* {{{ hasChildren()
- */
-SXE_METHOD(hasChildren)
-{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
- php_sxe_object *child = php_sxe_fetch_object(sxe->iter.data TSRMLS_CC);
- xmlNodePtr node;
+ sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+ GET_NODE(sxe, node);
- GET_NODE(child, node);
+ array_init(return_value);
if (node) {
- 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;
- }
+ child = node->children;
+ while (child) {
+ if (node->type == XML_ELEMENT_NODE) {
+ MAKE_STD_ZVAL(value);
+ _node_as_zval(sxe, child, value TSRMLS_CC);
+ add_next_index_zval(return_value, value);
}
- } while (0);
- if (node->type == XML_ELEMENT_NODE) {
- break;
+ child = child->next;
}
-next_iter:
- node = node->next;
}
- RETURN_BOOL(node ? 1 : 0);
-}
-/* }}} */
-
-/* {{{ getChildren()
- */
-SXE_METHOD(getChildren)
-{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
-
- return_value->type = IS_OBJECT;
- return_value->value.obj = zend_objects_store_clone_obj(sxe->iter.data TSRMLS_CC);
}
/* }}} */
@@ -1582,14 +1533,7 @@ static zend_function_entry sxe_functions[] = {
SXE_ME(validate_schema_file, NULL, ZEND_ACC_PUBLIC)
#endif
SXE_ME(xsearch, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(rewind, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(hasMore, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(current, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(key, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(next, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(hasChildren, NULL, ZEND_ACC_PUBLIC)
SXE_ME(getChildren, NULL, ZEND_ACC_PUBLIC)
- SXE_ME(count, NULL, ZEND_ACC_PUBLIC)
SXE_ME(attributes, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
diff --git a/ext/simplexml/tests/017.phpt b/ext/simplexml/tests/017.phpt
index de2823c40c..355ac5f599 100644
--- a/ext/simplexml/tests/017.phpt
+++ b/ext/simplexml/tests/017.phpt
@@ -35,10 +35,10 @@ function print_xml($xml) {
}
function print_xml2($xml) {
- $persons = $xml->count("person");
+ $persons = count($xml->person);
for ($i=0;$i<$persons;$i++) {
echo "person: ".$xml->person[$i]['name']."\n";
- $children = $xml->person[$i]->count("child");
+ $children = count($xml->person[$i]->child);
for ($j=0;$j<$children;$j++) {
echo " child: ".$xml->person[$i]->child[$j]['name']."\n";
}