PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Theory of Operation

To use Zend_Dom_Query, you instantiate a Zend_Dom_Query object, optionally passing a document to query (a string). Once you have a document, you can use either the query() or queryXpath() methods; each method will return a Zend_Dom_Query_Result object with any matching nodes.

The primary difference between Zend_Dom_Query and using DOMDocument + DOMXPath is the ability to select against CSS selectors. You can utilize any of the following, in any combination:

  • element types: provide an element type to match: 'div', 'a', 'span', 'h2', etc.

  • style attributes: CSS style attributes to match: '.error', 'div.error', 'label.required', etc. If an element defines more than one style, this will match as long as the named style is present anywhere in the style declaration.

  • id attributes: element ID attributes to match: '#content', 'div#nav', etc.

  • arbitrary attributes: arbitrary element attributes to match. Three different types of matching are provided:

    • exact match: the attribute exactly matches the string: 'div[bar="baz"]' would match a div element with a "bar" attribute that exactly matches the value "baz".

    • word match: the attribute contains a word matching the string: 'div[bar~="baz"]' would match a div element with a "bar" attribute that contains the word "baz". '<div bar="foo baz">' would match, but '<div bar="foo bazbat">' would not.

    • substring match: the attribute contains the string: 'div[bar*="baz"]' would match a div element with a "bar" attribute that contains the string "baz" anywhere within it.

  • direct descendents: utilize '>' between selectors to denote direct descendents. 'div > span' would select only 'span' elements that are direct descendents of a 'div'. Can also be used with any of the selectors above.

  • descendents: string together multiple selectors to indicate a hierarchy along which to search. 'div .foo span #one' would select an element of id 'one' that is a descendent of arbitrary depth beneath a 'span' element, which is in turn a descendent of arbitrary depth beneath an element with a class of 'foo', that is an descendent of arbitrary depth beneath a 'div' element. For example, it would match the link to the word 'One' in the listing below:

    <div>
    <table>
        <tr>
            <td class="foo">
                <div>
                    Lorem ipsum <span class="bar">
                        <a href="/foo/bar" id="one">One</a>
                        <a href="/foo/baz" id="two">Two</a>
                        <a href="/foo/bat" id="three">Three</a>
                        <a href="/foo/bla" id="four">Four</a>
                    </span>
                </div>
            </td>
        </tr>
    </table>
    </div>
    

Once you've performed your query, you can then work with the result object to determine information about the nodes, as well as to pull them and/or their content directly for examination and manipulation. Zend_Dom_Query_Result implements Countable and Iterator, and store the results internally as DOMNodes and DOMElements. As an example, consider the following call, that selects against the HTML above:

<?php
$dom 
= new Zend_Dom_Query($html);
$results $dom->query('.foo .bar a');

$count count($results); // get number of matches: 4
foreach ($results as $result) {
    
// $result is a DOMElement
}

Zend_Dom_Query also allows straight XPath queries utilizing the queryXpath() method; you can pass any valid XPath query to this method, and it will return a Zend_Dom_Query_Result object.

Zend Framework