I'm using PHP DOM and I'm trying to get an element within a DOM node that have a given class name. What's the best way to get that sub-element?
Update: I ended up using Mechanize
for PHP which was much easier to work with.
I'm using PHP DOM and I'm trying to get an element within a DOM node that have a given class name. What's the best way to get that sub-element?
Update: I ended up using Mechanize
for PHP which was much easier to work with.
Using simpleXML:
$xml = new SimpleXMLElement($xmlstr);
echo $xml->file['path']."n";
Output:
http://www.thesite.com/download/eysjkss.zip
You can use XPath on your DOMDocument as follows:
$doc->loadHTML($article_header);
$xpath = new DOMXpath($doc);
$imagesAndIframes = $xpath->query('//img | //iframe');
$length = $imagesAndIframes->length;
for ($i = 0; $i < $length; $i++) {
$element = $imagesAndIframes->item($i);
if ($element->tagName == 'img') {
echo 'img';
} else {
echo 'iframe';
}
}
The problem is that the NodeList returned to you is "live" - it changes as you alter the class name. That is, when you change the class on the first element, the list is immediately one element shorter than it was.
Try this:
while (elementArray.length) {
elementArray[0].className = "exampleClassComplete";
}
(There's no need to use setAttribute()
to set the "class" value - just update the "className" property. Using setAttribute()
in old versions of IE wouldn't work anyway.)
Alternatively, convert your NodeList to a plain array, and then use your indexed iteration:
elementArray = [].slice.call(elementArray, 0);
for (var i = 0; i < elementArray.length; ++i)
elementArray[i].className = "whatever";
As pointed out in a comment, this has the advantage of not relying on the semantics of NodeList objects. (Note also, thanks again to a comment, that if you need this to work in older versions of Internet Explorer, you'd have to write an explicit loop to copy element references from the NodeList to an array.)
This works
div {
display:table;
}
input {
display:table-footer-group;
}
label {
display:table-header-group;
}
http://jsfiddle.net/v8xTC/
Update: Xpath version of
*[@class~='my-class']
css selectorSo after my comment below in response to hakre's comment, I got curious and looked into the code behind
Zend_Dom_Query
. It looks like the above selector is compiled to the following xpath (untested):[contains(concat(' ', normalize-space(@class), ' '), ' my-class ')]
So the PHP would be:
Basically, all we do here is normalize the
class
attribute so that even a single class is bounded by spaces, and the complete class list is bounded in spaces. Then append the class we are searching for with a space. This way we are effectively looking for and find only instances ofmy-class
.Use an xpath selector?
If it is only ever one type of element you can replace the
*
with the particular tagname.If you need to do a lot of this with very complex selector I would recommend
Zend_Dom_Query
which supports CSS selector syntax (a la jQuery):