根据DOMDocument::getElementsByTagName
的文档,我可以使用"*"
参数调用函数,并从某些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>
虽然我期待着这样的事情:
<html><body><div>helloMODIFIED</div><div>byeMODIFIED</div></body></html>
DOMDocument::getElementsByTagName
方法不应该返回HTML代码中可用的HTML元素列表吗?
注意:我需要显式地创建DOMText实例,因为我需要它在PHP5.4中工作。DOMNode::textContent
仅可从PHP5.6编写
发布于 2016-11-07 07:41:45
如果第一个参数是DOMDocument::getElementsByTagName
,则'*'
方法实际上返回所有标记。但是,在第一次迭代时,代码将<body>
标记(包括所有子节点)替换为文本节点。
迭代节点,并且只修改具有nodeType
属性等于XML_TEXT_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();
注意,对于PHP5.6.1和更新版本,您不需要显式地创建DOMText
实例,因为DOMNode::textContent
属性可以进行读写访问。因此,您可以简单地通过为该属性分配一个字符串值来修改文本。只需确保该节点没有除XML_TEXT_NODE
以外的其他子节点。
上面的代码检查trim($child->textContent)
是否为空,因为文档可能包含额外的空格字符(包括换行符),例如:
<div><!-- newline/spaces -->
<span>text</span><!-- newline/spaces -->
</div><!-- newline/spaces -->
发布于 2016-11-07 08:08:55
这个函数'DOMDocument::getElementsByTagName‘返回一个包含所有元素的类DOMNodeList的新实例。
它工作得很好:
<?php
$dom = new DOMDocument();
$dom->loadHTML("<html><body><div>hello</div><div>bye</div></body></html>");
$nodes = $dom->getElementsByTagName("*");
foreach ($nodes as $node) {
echo $node->tagName."<br />";
}
?>
它输出文档的所有标记。
也许你需要这样的东西:
<?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);
?>
发布于 2016-11-07 07:56:51
试试这个:-
foreach($dom->getElementsByTagName('*') as $element ){
}
https://stackoverflow.com/questions/40467507
复制相似问题