如何获取PHP中所有html元素的列表?
根据的文档,我可以使用如何获取PHP中所有html元素的列表?,php,html,dom,Php,Html,Dom,根据的文档,我可以使用“*”参数调用函数,并从一些HTML代码中获取所有HTML元素的列表 但是,使用以下代码: <?php $dom = new DOMDocument(); $dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>"); $nodes = $dom->getElem
“*”
参数调用函数,并从一些HTML代码中获取所有HTML元素的列表
但是,使用以下代码:
<?php
$dom = new DOMDocument();
$dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
$nodes = $dom->getElementsByTagName("*");
foreach ($nodes as $node) {
$new_text= new DOMText($node->textContent."MODIFIED");
$node->removeChild($node->firstChild);
$node->appendChild($new_text);
}
$content = $dom->saveHTML();
echo $content;
?>
我只得到一个元素的列表,上面代码的执行结果是:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>hellobyeMODIFIED</html>
Hellobye修改
虽然我希望这样:
<html><body><div>helloMODIFIED</div><div>byeMODIFIED</div></body></html>
helloMODIFIEDbyeMODIFIED
DOMDocument::getElementsByTagName
方法不应该返回HTML代码中尽可能多的HTML元素的列表吗
注意:我需要显式地创建DOMText实例,因为我需要它在PHP5.4中工作
DOMNode::textContent
仅可从PHP5.6进行写入DOMDocument::getElementsByTagName
方法实际返回所有标记,如果第一个参数是“*”
。但是,在第一次迭代时,您的代码将
标记(包括所有子节点)替换为文本节点
迭代节点,仅修改nodeType
属性等于XML\u TEXT\u NODE
的节点:
$nodes = $dom->getElementsByTagName('*');
foreach ($nodes as $node) {
for ($child = $node->firstChild; $child; $child = $child->nextSibling) {
if (! ($child->nodeType === XML_TEXT_NODE && trim($child->textContent))) {
continue;
}
// The textContent is writable since PHP 5.6.1
if (PHP_VERSION_ID >= 50601) {
$child->textContent .= 'MODIFIED';
continue;
}
// For older versions, create DOMText explicitly
$text = new DOMText($child->textContent . 'MODIFIED');
try {
if ($child->parentNode->replaceChild($text, $child))
$child = $text;
} catch (Exception $e) {
trigger_error("Failed to modify text '$child->textContent': "
. $e->getMessage(), E_USER_WARNING);
}
}
}
echo $dom->saveHTML();
注意,对于PHP版本5.6.1及更高版本,您不需要显式创建DOMText
实例,因为DOMNode::textContent
属性可用于读写。因此,您可以通过为该属性指定字符串值来简单地修改文本。仅确保该节点除了XML\u TEXT\u节点
之外没有其他子节点
上面的代码检查trim($child->textContent)
是否为空,因为文档可能包含额外的空格字符(包括换行符),例如:
文本
如果第一个参数是“*”
,则DOMDocument::getElementsByTagName方法实际上返回所有标记。但是,在第一次迭代时,您的代码将
标记(包括所有子节点)替换为文本节点
迭代节点,仅修改nodeType
属性等于XML\u TEXT\u NODE
的节点:
$nodes = $dom->getElementsByTagName('*');
foreach ($nodes as $node) {
for ($child = $node->firstChild; $child; $child = $child->nextSibling) {
if (! ($child->nodeType === XML_TEXT_NODE && trim($child->textContent))) {
continue;
}
// The textContent is writable since PHP 5.6.1
if (PHP_VERSION_ID >= 50601) {
$child->textContent .= 'MODIFIED';
continue;
}
// For older versions, create DOMText explicitly
$text = new DOMText($child->textContent . 'MODIFIED');
try {
if ($child->parentNode->replaceChild($text, $child))
$child = $text;
} catch (Exception $e) {
trigger_error("Failed to modify text '$child->textContent': "
. $e->getMessage(), E_USER_WARNING);
}
}
}
echo $dom->saveHTML();
注意,对于PHP版本5.6.1及更高版本,您不需要显式创建DOMText
实例,因为DOMNode::textContent
属性可用于读写。因此,您可以通过为该属性指定字符串值来简单地修改文本。仅确保该节点除了XML\u TEXT\u节点
之外没有其他子节点
上面的代码检查trim($child->textContent)
是否为空,因为文档可能包含额外的空格字符(包括换行符),例如:
文本
试试这个:-
foreach($dom->getElementsByTagName('*') as $element ){
}
试试这个:-
foreach($dom->getElementsByTagName('*') as $element ){
}
此函数“DOMDocument::getElementsByTagName”返回包含所有元素的类DOMNodeList的新实例
而且效果很好:
它输出文档的所有标记
可能您需要smth,如:
<?php
$dom = new DOMDocument();
$dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
$nodes = $dom->getElementsByTagName("*");
foreach ($nodes as $node) {
if ($node->tagName=='div'){
$node->nodeValue .= "new content";
}
}
$content = $dom->saveHTML();
echo htmlspecialchars($content);
?>
此函数“DOMDocument::getElementsByTagName”返回包含所有元素的类DOMNodeList的新实例
而且效果很好:
它输出文档的所有标记
可能您需要smth,如:
<?php
$dom = new DOMDocument();
$dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
$nodes = $dom->getElementsByTagName("*");
foreach ($nodes as $node) {
if ($node->tagName=='div'){
$node->nodeValue .= "new content";
}
}
$content = $dom->saveHTML();
echo htmlspecialchars($content);
?>
您的元素具有相同的标记名…@Alexis,是的,但是如果我通过getElementsByTagName(“div”)更改getElementsByTagName(*”),那么我会得到我想要的结果,并且元素仍然具有相同的标记名。@MarcosFernandez,不清楚您到底想要实现什么。是否要修改所有文本节点?还是要修改具有文本节点的叶子(最后一个标记)的所有文本节点?例如,如何修改此序列textabcdef
?@Ruslan Osmanov我需要处理页面中的所有文本元素。它们不一定会被修改,但我必须检查它们。在您的示例中,如果所有这些文本元素都应该修改,那么结果将是:textModifiedABC修改dDefModified
您提到您需要它在PHP5.4中工作,即使您知道5.6中的功能可能会有所帮助。升级有多困难?实际上,5.4和5.6之间没有明显的向后兼容性问题,因此升级应该非常容易。此外,5.4不再受支持,因此您确实应该考虑升级。您的元素具有相同的标记名…@Alexis,是的,但是如果我通过getElementsByTagName(“div”)更改getElementsByTagName(*),那么我会得到我想要的结果,并且元素仍然具有相同的标记名。@MarcosFernandez,现在还不清楚你到底想要实现什么。是否要修改所有文本节点?还是要修改具有文本节点的叶子(最后一个标记)的所有文本节点?例如,如何修改此序列textabcdef
?@Ruslan Osmanov我需要处理页面中的所有文本元素。它们不一定会被修改,但我必须检查它们。在您的示例中,如果所有这些文本元素都应该修改,那么结果将是:textModifiedABC修改dDefModified
您提到您需要它在PHP5.4中工作,即使您知道5.6中的功能可能会有所帮助。升级有多困难?实际上,5.4和5.6之间没有明显的向后兼容性问题,因此升级应该非常容易。另外,5.4不再受支持,所以你真的应该考虑升级了。谢谢,差不多了!只有一件事:我确实需要显式地创建DOMText实例,因为我需要它在PHP5.4中工作DOMNode::textContent
只能从PHP5.6上进行编写。我仍然无法在5.4上完成此操作。非常感谢!。我被孩子->父母节点的事情缠住了。谢谢你的解释。节省了很多时间!谢谢,差不多了!只有一件事:我确实需要显式地创建DOMText实例,因为我需要这样做