7

好吧,所以我在这里有一个奇怪的案例,我只是想不通。

我想解析网站上的列表。HTML 看起来有点像这样:

<!-- ... -->
<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>
<!-- ... -->

现在我想获取所有列表项。我为此使用 DOMDocument 类。到目前为止,效果很好:

$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);
}

但现在,我正在寻找一种简单的方法来读出data-text属性。我所做的是:

foreach ($items as $item) {
     echo $item->getAttribute('data-text');
}

这对于第一个项目来说效果很好,但是它会使 foreach 循环崩溃。输出是:

项目 1
致命错误:在第 44 行的 example.php 中调用未定义的方法 DOMText::getAttribute()

我在这里没有得到的是调用该getAttribute方法如何更改 foreach 循环的上下文。所以这里有两个问题:

  1. 调用该方法如何搞砸我的 foreach 循环?其次,最优雅的解决方法是什么?
  2. 我意识到我可以循环$item->attributes with另一个 foreach 方法,然后比较属性名称data-text并在匹配的情况下读取值,但肯定有更好的方法来做到这一点?!
4

1 回答 1

8

问题是ul有文本节点作为子节点以及lis 文本节点没有属性,因此您会收到错误消息。在尝试访问其属性之前,只需测试子节点是否是元素节点

foreach ($items as $item) {
         if ($item->nodeType == XML_ELEMENT_NODE)
         echo $item->getAttribute('data-text');
}

您也可以使用getElementsByTagName(),尽管如果您有嵌套列表,li其中的 s 也会被选中。

$items = $list->getElementsByTagName('li');
foreach ($items as $item) {
    echo $item->getAttribute('data-text');
}
于 2013-01-28T22:02:20.990 回答