2013-03-05 66 views
0

考慮以下HTML的孩子:PHP的DOM和XPath - 更換節點,但保留舊節點

<html> 
    <title>Xyz</title> 
    <body> 
     <div> 
      <div class='mycls'> 
       <div>1 Books</div> 
       <div>2 Papers</div> 
       <div>3 Pencils</div> 
      </div> 
     </div> 
    <body> 
</html> 
$dom = new DOMDocument(); 
$dom->loadHTML([loaded html of remote url through curl]); 
$xpath = new DOMXPath($dom); 
$nodes = $xpath->query('html/body/div[@class="mycls"]'); 

到這裏它的做工精細,我需要更換節點,以獲得以下內容:

<body> 
     <div> 
      <span> 
       <div>1 Books</div> 
       <div>2 Papers</div> 
       <div>3 Pencils</div> 
      </span> 
     </div> 
    <body> 

回答

1

類似下面應該爲你工作:

$dom = new DOMDocument(); 
$dom->loadHTML($html); 
$xpath = new DOMXPath($dom); 
$oldNode = $xpath->query('//div[@class="mycls"]')->item(0); 
$span = $dom->createElement('span'); 

if ($oldNode->hasChildNodes()) { 
    $children = []; 
    foreach ($oldNode->childNodes as $child) { 
     $children[] = $child; 
    } 
    foreach ($children as $child) { 
     $span->appendChild($child->parentNode->removeChild($child)); 
    } 
} 

$oldNode->parentNode->replaceChild($span, $oldNode); 

echo htmlspecialchars($dom->saveHTML()); 

演示:http://codepad.viper-7.com/WNTrR5

注意,在演示中,我也有固定的HTML這是完全打破:-)

如果你演示是真的,你是來自卷邊呼叫取回的HTML,你不能改變它(無控制權它),你可以這樣做:

$libxmlErrors = libxml_use_internal_errors(true); // at the start 

libxml_use_internal_errors($libxmlErrors); // at the end 

爲了防止錯誤彈出

+0

孩子能有更多的兒童, 像

booksGoogle
..... – 2013-03-05 13:12:10

+0

@ user1966604更新 – PeeHaa 2013-03-05 13:14:06

+0

反正是有讓所有的孩子一下子把它們添加到一個新的節點, allchilds = oldnode-> getallchilds(); newnode-> appendchild(allchilds); oldNode-> parentNode-> replaceChild(newnode,oldNode); 明白了嗎? – 2013-03-05 13:16:23