使用PHP和xPath提取干净的文本表

使用PHP和xPath提取干净的文本表,php,xpath,Php,Xpath,我使用下面的代码从HTML文件中提取值。代码返回一个文本块。我想知道如何改进代码并将这段代码的元素提取到一个干净的表中 文件: 这个怎么样 $doc = new DOMDocument(); @$doc->loadHTMLFile('file.htm'); $xpath = new DOMXPath($doc); $list = $xpath->evaluate("//div[contains(@class, 'class1')]/a"); foreach ($list as

我使用下面的代码从HTML文件中提取值。代码返回一个文本块。我想知道如何改进代码并将这段代码的元素提取到一个干净的表中

文件:

这个怎么样

$doc = new DOMDocument();
@$doc->loadHTMLFile('file.htm');

$xpath = new DOMXPath($doc);

$list = $xpath->evaluate("//div[contains(@class, 'class1')]/a");

foreach ($list as $element)
{
    $nextElement = $element->nextSibling;
    while ($nextElement->nodeType != XML_ELEMENT_NODE) {
        $nextElement = $nextElement->nextSibling;
    }

    echo $element->nodeValue . ' | ' . trim($nextElement->nodeValue) .  PHP_EOL;
}

我不太清楚你为什么想要
以及
PHP_EOL
,所以我把它们忘了,但是你可以把它们放回你需要的地方。

或者,如果你想确保你分别输出每个表,你可以这样做。它假设保持了顺序,我认为XML/XPath并不总是保证这一点,但在实践中,大多数实现通常都是这样:

$doc = new DOMDocument();
$doc->loadHTMLFile('file.htm');

$xpath = new DOMXPath($doc);

$list = $xpath->evaluate("//div[contains(@class, 'class1')]");

foreach ($list as $element)
{
    $column1 = $xpath->query("//a", $element);
    $column2 = $xpath->query("//div/p", $element);

    for ($i = 0; $i < $column1->length; $i++) {
        echo $column1->item($i)->nodeValue . ' | ' . $column2->item($i)->nodeValue .  PHP_EOL;
    }
}

for($i=0;$i<$column1->length;$i++){
您遇到了什么错误?当我在上面的示例html上尝试它时,它起了作用。如果html中缺少某些column2值,或者它们的格式不同,则可能会失败,在这种情况下,您需要进行一些额外的错误检查。问题是,在html的结构中没有强制执行这些行,因此您需要必须分别循环遍历这些列,并假设它们的长度相同,或者检查代码并决定如果它们不是,您要做什么。或者使用这种方法和我的另一个答案相结合。如上所述循环遍历
a
元素,但然后为每个元素获取下一个元素,而不是循环遍历第2列。您可以我不想检查节点名是否为'div',如果没有则忽略它。请记住,
a
之后和
div
之前可能有一个空文本节点-这就是为什么我的示例检查节点类型是否为XML\u元素\u节点。节点不是空的或不同的格式。我可以通过更改
$column1来解决此问题
$column2
。我将尝试修改循环的组合,因为我认为该方法在原则上是有效的。我已编辑了我的答案,以包含另一种方法。我希望这些方法中的一种对您有用。如果正确,我将感谢您的支持投票和/或标记!
 txt1 | hello1
 txt2 | hello2
$doc = new DOMDocument();
@$doc->loadHTMLFile('file.htm');

$xpath = new DOMXPath($doc);

$list = $xpath->evaluate("//div[contains(@class, 'class1')]/a");

foreach ($list as $element)
{
    $nextElement = $element->nextSibling;
    while ($nextElement->nodeType != XML_ELEMENT_NODE) {
        $nextElement = $nextElement->nextSibling;
    }

    echo $element->nodeValue . ' | ' . trim($nextElement->nodeValue) .  PHP_EOL;
}
$doc = new DOMDocument();
$doc->loadHTMLFile('file.htm');

$xpath = new DOMXPath($doc);

$list = $xpath->evaluate("//div[contains(@class, 'class1')]");

foreach ($list as $element)
{
    $column1 = $xpath->query("//a", $element);
    $column2 = $xpath->query("//div/p", $element);

    for ($i = 0; $i < $column1->length; $i++) {
        echo $column1->item($i)->nodeValue . ' | ' . $column2->item($i)->nodeValue .  PHP_EOL;
    }
}
foreach ($list as $element)
{
    $column1 = $xpath->query("//a", $element);

    for ($i = 0; $i < $column1->length; $i++) {
        $field1 = $column1->item($i);
        $field2 = $xpath->query("following-sibling::div", $field1)->item(0);

        echo $field1->nodeValue . ' | ' . trim($field2->nodeValue) .  PHP_EOL;
    }
}