2012-11-07 101 views
4
字符串替换节点

可能重复:
PHP - How to replace a phrase with another?如何使用DOM文档

我需要这块HTML

<html> 
    <body> 
     Lorum ipsum <a href="http://google.com">click here</a> dolores lorem. 
     Lorum ipsum <a href="http://stackoverflow.com">click here too</a> dolores lorem. 
    </body> 
</html> 

变换为:

<html> 
    <body> 
     Lorum ipsum @@[email protected]@ dolores lorem. 
     Lorum ipsum @@[email protected]@ dolores lorem. 
    </body> 
</html> 

这是如何使用Domdocument实现的(我对een正则表达式解决方案不感兴趣)?

+0

用DOMText节点替换所有的DOME元素。 – Gordon

回答

4

到目前为止,您还没有显示任何代码,因此不清楚您运行的是哪个问题。我只能假设这是因为如果你迭代改变它的链接列表,迭代将失效。所以只有第一个元素被替换。

使用for循环可以帮助在这里只获得每次迭代的第一个元素。它还允许初始化并增加替换中需要的数字的计数变量。

更换本身可以用replaceChild轻松完成。环例如:

for($c = 1; $a = $doc->getElementsByTagName('a')->item(0); $c++) { 
    $a->parentNode->replaceChild(
     $doc->createTextNode(sprintf("@@%[email protected]@", $c)), 
     $a 
    ); 
} 

$doc->getElementsByTagName('a')->item(0)呼叫将如果没有这样的元素存在(再)返回NULL。这是循环的退出条件。

完整的示例:

$html = '<html><body> 
    Lorum ipsum <a href="http://google.com">click here</a> dolores lorem. 
    Lorum ipsum <a href="http://stackoverflow.com">click here too</a> dolores lorem. 
</body></html>'; 

$doc = new DOMDocument(); 
$doc->loadHtml($html); 

for($c = 1; $a = $doc->getElementsByTagName('a')->item(0); $c++) { 
    $a->parentNode->replaceChild(
     $doc->createTextNode(sprintf("@@%[email protected]@", $c)), 
     $a 
    ); 
} 

echo $doc->saveHTML(); 

输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html><body> 
    Lorum ipsum @@[email protected]@ dolores lorem. 
    Lorum ipsum @@[email protected]@ dolores lorem. 
</body></html> 

我希望这是有帮助的。

+0

每次迭代都不会有'$ doc-> getElementsByTagName('a')'是一个性能问题? – Carlos

+0

@jackflash:不,它的运行速度非常快。我甚至会认为它的工作更快,然后保留元素清单。我曾经在某种答案中这样做过,但我根本不担心这里的表现。不要猜测性能问题,度量标准,以便知道是否存在*真实*问题。除非你不这样做,否则不关心它。只是我2美分。 – hakre

+0

@jackflash:只要看到使用xpath结果,它可能更直接,如果你有兴趣的话。我编辑了现有的答案来使用它:http://stackoverflow.com/a/3389140/367456 – hakre