Alright, so I have an odd case here that I just can't figure out.
I want to parse a list on a website. The HTML looks somewhat like this:
<!-- ... -->
<ul id="foo">
<li data-text="item 1">Blabla</li>
<li data-text="item 2">Blabla</li>
<li data-text="item 3">Blabla</li>
<li data-text="item 4">Blabla</li>
</ul>
<!-- ... -->
Now I want to grab all the list items. I use the DOMDocument-class for that. So far, that works out just fine:
$dom = new DOMDocument();
if (!$dom->loadHTML($html)) {
die ('Could not parse...');
}
$list = $dom->getElementById('foo');
$items = $list->childNodes;
foreach ($items as $item) {
print_r($item);
}
But now, I'm looking for a simple method to read out the data-text
attribute. What I did was:
foreach ($items as $item) {
echo $item->getAttribute('data-text');
}
This works just fine for the very first item, but then it crashes the foreach-loop. The output is:
item 1
Fatal error: Call to undefined method DOMText::getAttribute() in example.php on line 44
What I don't get here is how calling the getAttribute
method changes the context of the foreach loop. So here are two questions:
$item->attributes with
yet another
foreach method, then compare the attribute name to data-text
and
read the value in case of a match, but there surely has to be a
better way to do so?!The problem is the ul
has text nodes as children along with the li
s textnodes do not have attribute therefore you get an error. just test if the child is an element node before you try to access its attribute
foreach ($items as $item) {
if ($item->nodeType == XML_ELEMENT_NODE)
echo $item->getAttribute('data-text');
}
You can also use getElementsByTagName()
, although if you have nested lists the li
s in them will also be selected.
$items = $list->getElementsByTagName('li');
foreach ($items as $item) {
echo $item->getAttribute('data-text');
}