anewt-developers team mailing list archive
-
anewt-developers team
-
Mailing list archive
-
Message #00216
[Branch ~uws/anewt/anewt.uws] Rev 1756: [xml/dom] Implement ArrayAccess interface for DOM nodes
------------------------------------------------------------
revno: 1756
committer: Wouter Bolsterlee <uws@xxxxxxxxx>
branch nick: anewt.uws
timestamp: Tue 2010-02-16 20:09:07 +0100
message:
[xml/dom] Implement ArrayAccess interface for DOM nodes
The main XML DOM node class now implements the ArrayAccess
interface.
This means that you can now use fancy code like this:
$div = ax_div();
$div['style'] = 'background-color: red;'
$div[] = ax_p('The first paragraph in the div.');
$div[] = ax_p('The second paragraph in the div.');
$div[0]['id'] = 'first-paragraph';
$div[-1]['id'] = 'last-paragraph';
This works for all DOM nodes, including XML document
fragments (except for setting attributes, since fragments do
not have attributes.)
Part of bug #514479.
modified:
xml/dom.lib.php
--
lp:anewt
https://code.launchpad.net/~uws/anewt/anewt.uws
Your team Anewt developers is subscribed to branch lp:anewt.
To unsubscribe from this branch go to https://code.launchpad.net/~uws/anewt/anewt.uws/+edit-subscription.
=== modified file 'xml/dom.lib.php'
--- xml/dom.lib.php 2010-01-06 20:56:33 +0000
+++ xml/dom.lib.php 2010-02-16 19:09:07 +0000
@@ -34,7 +34,7 @@
* \todo: Implement first_child, last_child, previous_sibling and next_sibling
* attributes in node trees.
*/
-abstract class AnewtXMLDomNode
+abstract class AnewtXMLDomNode implements ArrayAccess
{
/**
* The node type.
@@ -238,6 +238,7 @@
$out = $new_child;
}
+ unset ($new_child);
return $out;
}
@@ -341,7 +342,7 @@
assert('$old_child instanceof AnewtXMLDomNode;');
/* TODO: implement */
- trigger_error('Not implemented', E_USER_ERROR);
+ throw new AnewtException('Not implemented: %s::%s()', __CLASS__, __FUNCTION__);
}
/**
@@ -382,6 +383,110 @@
{
return (bool) $this->child_nodes;
}
+
+ /** \{
+ * \name Array access methods
+ *
+ * TODO: document behaviour
+ */
+
+ public function offsetGet($offset)
+ {
+ /* Elements */
+
+ if (is_int($offset))
+ {
+ $n_child_nodes = count($this->child_nodes);
+
+ if ($offset < 0)
+ {
+ if (abs($offset) > $n_child_nodes)
+ throw new AnewtException(
+ 'No element with index %d (element has only %d child nodes)', $offset, $n_child_nodes);
+
+ $offset += $n_child_nodes;
+ }
+
+ return $this->child_nodes[$offset];
+ }
+
+
+ /* Attributes */
+
+ if (is_string($offset))
+ return $this->get_attribute($offset);
+
+ throw new AnewtException('Array offset must be a string (for attributes) or an integer (for child nodes)');
+ }
+
+ public function offsetSet($offset, $value)
+ {
+ /* Elements */
+
+ if (is_int($offset))
+ /* FIXME: hook into replace_child() when implemented */
+ throw new AnewtException('Replacing child nodes is not implemented');
+
+ elseif (is_null($offset))
+ /* Array append operator was used, e.g.
+ *
+ * $parent_node[] = $child-node;
+ *
+ * This is perhaps the most useful part of the ArrayAccess
+ * interface for this class, since it can make XML (or XHTML) code
+ * much easier to read and write.
+ */
+ $this->append_child($value);
+
+
+ /* Attributes */
+
+ elseif (is_string($offset))
+ $this->set_attribute($offset, $value);
+
+ else
+ throw new AnewtException('Array offset must be a string (for attributes) or an integer (for child nodes)');
+ }
+
+ public function offsetExists($offset)
+ {
+ /* Elements */
+
+ if (is_int($offset))
+ return array_key_exists($offset, $this->child_nodes);
+
+
+ /* Attributes */
+
+ elseif (is_string($offset))
+ return $this->has_attributes($offset);
+
+
+ throw new AnewtException('Array offset must be a string (for attributes) or an integer (for child nodes)');
+ }
+
+ public function offsetUnset($offset)
+ {
+ /* Elements */
+
+ if (is_int($offset))
+ {
+ /* Remove the child, if set */
+ if ($this->offsetExists($offset))
+ return $this->remove_child($this->offsetGet($offset));
+ }
+
+
+ /* Attributes */
+
+ elseif (is_string($offset))
+ $this->remove_attribute($offset);
+
+ else
+ throw new AnewtException('Array offset must be a string (for attributes) or an integer (for child nodes)');
+ }
+
+ /** \} */
}