我使用以下代码从HTML文件中提取值。代码返回一个文本块。我想知道如何改进代码并将此代码块的元素提取到干净的表中。
文件:
<div class=class1>
<a href="">txt1</a>
<div class=lvl2>
<p>hello1</p>
</div>
<a href="">txt2</a>
<div class=lvl2>
<p>hello2</p>
</div>
</div>
代码:
$doc = new DOMDocument();
@$doc->loadHTMLFile('file.htm');
$xpath = new DOMXPath($doc);
$list = $xpath->evaluate("//div[contains(@class, 'class1')]");
foreach ($list as $element)
{
echo '<p>' . $element->nodeValue . PHP_EOL . '</p>';
}
期望的输出:
txt1 | hello1
txt2 | hello2
答案 0 :(得分:1)
或者,如果你想确保单独输出每个表,你可以这样做。它假定维护了排序,我认为并不总是保证使用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;
}
}
我已从@
方法中删除loadHTMLFile
错误抑制 - 我认为您不想使用它,因为如果失败,您将在以后遇到错误,并将其遗漏将使你的问题的原因更明确。
修正:如果你不想在两列上单独迭代,这是你可以构建循环的另一种方法。但是,如果每列中的行数在html中不匹配,它可能仍会失败:
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;
}
}
答案 1 :(得分:0)
这个怎么样?:
$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;
}
我不太确定你为什么要<p>
以及PHP_EOL
,所以我把它们排除了,但你可以把它们放回你需要的地方。