Skip to content
This repository

Allow NodeList to be accessed via array like syntax. #3078

Closed
wants to merge 1 commit into from

3 participants

Blaine Schmeisser Josey Morton Matthew Weier O'Phinney
Blaine Schmeisser

If we do a execute a selector and get back a NodeList and want just the first element we can now access it like so:

<?php
use Zend\Dom\Query;

$dom = new Query($html);
$results = $dom->execute('.foo .bar a');

$count = count($results); // get number of matches: 4

$results[2]->getAttribute('id'); // access individually

foreach ($results as $result) { // or iterate
    // $result is a DOMElement
}
?>

Where before you could only iterate them which is really ineffective for a lot of projects.

Blaine Schmeisser Allow NodeList to be accessed via array like syntax.
If we do a execute a selector and get back a NodeList and want just the first element we can now access it like so:

~~~ php
<?php
use Zend\Dom\Query;

$dom = new Query($html);
$results = $dom->execute('.foo .bar a');

$count = count($results); // get number of matches: 4

$results[2]->getAttribute('id'); // access individually

foreach ($results as $result) { // or iterate
    // $result is a DOMElement
}
?>
~~~

Where before you could only iterate them which is really ineffective for a lot of projects.
29cfd0b
Matthew Weier O'Phinney weierophinney referenced this pull request from a commit December 10, 2012
Matthew Weier O'Phinney [#3078] fix failing tests in 5.4.5
- DOMXPath::query() no longer raises an exception on failure; it now
  raises an E_WARNING. Updated code to detect an E_WARNING and raise an
  exception when discovered.
a65ce08
Matthew Weier O'Phinney weierophinney closed this in f40c4f5 December 10, 2012
Matthew Weier O'Phinney

Found an issue with PHP >= 5.4.1 -- DOMXPath::query() no longer throws an exception when it encounters extensions it does not know about. Updated the code to use the ErrorHandler so it can detect these situations.

Also: merged only to develop, as this is a new feature. It will release with 2.1.0.

Deleted user Unknown referenced this pull request from a commit December 10, 2012
Matthew Weier O'Phinney [#3078] fix failing tests in 5.4.5
- DOMXPath::query() no longer raises an exception on failure; it now
  raises an E_WARNING. Updated code to detect an E_WARNING and raise an
  exception when discovered.
9f1e8b5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Nov 27, 2012
Blaine Schmeisser Allow NodeList to be accessed via array like syntax.
If we do a execute a selector and get back a NodeList and want just the first element we can now access it like so:

~~~ php
<?php
use Zend\Dom\Query;

$dom = new Query($html);
$results = $dom->execute('.foo .bar a');

$count = count($results); // get number of matches: 4

$results[2]->getAttribute('id'); // access individually

foreach ($results as $result) { // or iterate
    // $result is a DOMElement
}
?>
~~~

Where before you could only iterate them which is really ineffective for a lot of projects.
29cfd0b
This page is out of date. Refresh to see the latest.
21  library/Zend/Dom/Exception/BadMethodCallException.php
... ...
@@ -0,0 +1,21 @@
  1
+<?php
  2
+/**
  3
+ * Zend Framework (http://framework.zend.com/)
  4
+ *
  5
+ * @link      http://github.com/zendframework/zf2 for the canonical source repository
  6
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7
+ * @license   http://framework.zend.com/license/new-bsd New BSD License
  8
+ * @package   Zend_Dom
  9
+ */
  10
+
  11
+namespace Zend\Dom\Exception;
  12
+
  13
+/**
  14
+ * Zend_Dom Exceptions
  15
+ *
  16
+ * @category   Zend
  17
+ * @package    Zend_Dom
  18
+ */
  19
+class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
  20
+{
  21
+}
48  library/Zend/Dom/NodeList.php
@@ -16,6 +16,7 @@
16 16
 use DOMNode;
17 17
 use DOMXPath;
18 18
 use Iterator;
  19
+use ArrayAccess;
19 20
 
20 21
 /**
21 22
  * Nodelist for DOM XPath query
@@ -23,7 +24,7 @@
23 24
  * @package    Zend_Dom
24 25
  * @subpackage Query
25 26
  */
26  
-class NodeList implements Iterator, Countable
  27
+class NodeList implements Iterator, Countable, ArrayAccess
27 28
 {
28 29
     /**
29 30
      * Number of results
@@ -175,4 +176,49 @@ public function count()
175 176
     {
176 177
         return $this->nodeList->length;
177 178
     }
  179
+
  180
+    /**
  181
+     * ArrayAccess: offset exists
  182
+     *
  183
+     * @return bool
  184
+     */
  185
+    public function offsetExists($key)
  186
+    {
  187
+        if (in_array($key, range(0, $this->nodeList->length - 1)) && $this->nodeList->length > 0) {
  188
+            return true;
  189
+        }
  190
+        return false;
  191
+    }
  192
+
  193
+    /**
  194
+     * ArrayAccess: get offset
  195
+     *
  196
+     * @return mixed
  197
+     */
  198
+    public function offsetGet($key)
  199
+    {
  200
+        return $this->nodeList->item($key);
  201
+    }
  202
+
  203
+    /**
  204
+     * ArrayAccess: set offset
  205
+     *
  206
+     * @return void
  207
+     * @throws Exception\BadMethodCallException when attemptingn to write to a read-only item
  208
+     */
  209
+    public function offsetSet($key, $value)
  210
+    {
  211
+        throw new Exception\BadMethodCallException('Attempting to write to a read-only list');
  212
+    }
  213
+
  214
+    /**
  215
+     * ArrayAccess: unset offset
  216
+     *
  217
+     * @return void
  218
+     * @throws Exception\BadMethodCallException when attemptingn to unset a read-only item
  219
+     */
  220
+    public function offsetUnset($key)
  221
+    {
  222
+        throw new Exception\BadMethodCallException('Attempting to unset on a read-only list');
  223
+    }
178 224
 }
44  tests/ZendTest/Dom/QueryTest.php
@@ -356,4 +356,48 @@ public function testLoadingXmlContainingDoctypeShouldFailToPreventXxeAndXeeAttac
356 356
         $this->setExpectedException("\Zend\Dom\Exception\RuntimeException");
357 357
         $this->query->queryXpath('/');
358 358
     }
  359
+
  360
+    public function testOffsetExists()
  361
+    {
  362
+        $this->loadHtml();
  363
+        $results = $this->query->execute('input');
  364
+
  365
+        $this->assertEquals(3, $results->count());
  366
+        $this->assertFalse($results->offsetExists(3));
  367
+        $this->assertTrue($results->offsetExists(2));
  368
+    }
  369
+
  370
+    public function testOffsetGet()
  371
+    {
  372
+        $this->loadHtml();
  373
+        $results = $this->query->execute('input');
  374
+
  375
+        $this->assertEquals(3, $results->count());
  376
+        $this->assertEquals('login', $results[2]->getAttribute('id'));
  377
+    }
  378
+
  379
+    /**
  380
+     * @expectedException Zend\Dom\Exception\BadMethodCallException
  381
+     */
  382
+    public function testOffsetSet()
  383
+    {
  384
+        $this->loadHtml();
  385
+        $results = $this->query->execute('input');
  386
+        $this->assertEquals(3, $results->count());
  387
+
  388
+        $results[0] = '<foobar />';
  389
+    }
  390
+
  391
+
  392
+    /**
  393
+     * @expectedException Zend\Dom\Exception\BadMethodCallException
  394
+     */
  395
+    public function testOffsetUnset()
  396
+    {
  397
+        $this->loadHtml();
  398
+        $results = $this->query->execute('input');
  399
+        $this->assertEquals(3, $results->count());
  400
+
  401
+        unset($results[2]);
  402
+    }
359 403
 }
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.