用PHP解析HTML以获得按类分组的兄弟元素


Parse HTML with PHP to get sibling elements grouped by class

我有一个巨大的HTML文档,我需要解析。该文档是<p>元素的列表,这些元素都是body标记的(直接)子元素。区别在于类名。结构如下:

    <p class="first-level"></p>
    <p class="second-level"></p>
    <p class="third-level"></p>
    <p class="third-level"></p>
    <p class="nth-levels just-for-demo-1"></p>
    <p class="nth-levels just-for-demo-1"></p>
    <p class="third-level"></p>
    <p class="second-level"></p>
    <p class="third-level"></p>
    <p class="nth-levels just-for-demo-2"></p>
    <p class="first-level"></p>
    <p class="second-level"></p>
    <p class="second-level"></p>
    <p class="third-level"></p>

以此类推。第n层可以是除first-levelsecond-levelthird-level以外的任何类名。基本上,它是一个多级<ul>元素,标记很差。

我想做的是解析它并获得所有<p>元素(包括标签,而不仅仅是innerHTML),这些元素位于上面的一个类名之间。

在上面的例子中,我想得到:

<p class="nth-levels just-for-demo-1"></p>
<p class="nth-levels just-for-demo-1"></p>

<p class="nth-levels just-for-demo-2"></p>

我到底该怎么做呢?谢谢你。

使用XPath:
//p[not(@class='first-level')][not(@class='second-level')][not(@class='third-level')]

来获取(非?)匹配的节点,然后您可以使用此答案来获取节点的outerHTML

另外,如果你熟悉jQuery,那么尝试将jQuery移植到PHP,你可以拥有一套强大的工具来匹配文档中的一组元素(选择器),就像你曾经使用jQuery一样,还有层次结构,属性过滤器,子过滤器等,参考

$doc = new DOMDocument;
$doc->loadHTML(...);
$query = '//p[contains(@class, "just-for-demo-")]';
$xpath = new DOMXPath($doc);
$entries = $xpath->query($query);
foreach ($entries as $entry)
{
  // not a best solution yet
  $attribute = '';
  foreach ($entry->attributes as $attr)
  {
    $attribute .= "{$attr->name}='"{$attr->value}'"";
  }
  echo "<{$entry->nodeName}{$attribute}>{$entry->nodeValue}</{$entry->nodeName}>";
}

可以打开文件(使用fopen或类似的方法),每次读取一行。然后只需检查所需的字符串是否在该行中(例如使用strstr),如果是,则将其添加到数组中或对该行进行所需的操作。注意:这只适用于段落在不同行的情况。

fopen文档

strstr文档