2011-03-12 79 views
3

Bascially我正在寫一個模板系統爲我的CMS和我想有一個模塊化結構,涉及人的標籤把這樣的:未捕獲的異常「拋出:DOMException」有消息「未找到錯誤」

<module name="news" /><include name="anotherTemplateFile" />這然後我想在我的php中找到並用動態html替換。

有人在這裏指出我對DOMDocument,但我已經遇到了一個問題。

我正試圖在我的模板中找到所有<include />標籤,並用一些簡單的html替換它們。這裏是我的模板代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<title>CMS</title> 
<include name="head" /> 
</head> 

<body> 

<include name="header" /> 

<include name="content" /> 

<include name="footer" /> 

</body> 
</html> 

這裏是我的PHP:

$template = new DOMDocument(); 
$template->load("template/template.tpl"); 

foreach($template->getElementsByTagName("include") as $include) { 
    $element = '<input type="text" value="'.print_r($include, true).'" />'; 
    $output = $template->createTextNode($element); 
    $template->replaceChild($output, $include); 
} 

echo $template->saveHTML(); 

現在,我得到的致命錯誤Uncaught exception 'DOMException' with message 'Not Found Error'

我看這件事,似乎是因爲我<include />標籤不一定是$template DIRECT兒童它不是取代他們。

如何獨立於血統來替換它們?

謝謝

湯姆

編輯

基本上我有各種各樣的腦電波。如果我做這樣的事情對我的PHP我看到它的努力做我想做的事情:

$template = new DOMDocument(); 
    $template->load("template/template.tpl"); 

    foreach($template->getElementsByTagName("include") as $include) { 
     $element = '<input type="text" value="'.print_r($include, true).'" />'; 
     $output = $template->createTextNode($element); 
     // this line is different: 
     $include->parentNode->replaceChild($output, $include); 
    } 

    echo $template->saveHTML(); 

但是似乎只改變1個occurence在我的HTML的<body> ......當我有3個。:/

+0

嘗試http://simplehtmldom.sourceforge.net/而不是DOM文檔 – yoda 2011-03-12 17:26:44

+1

@yoda你告訴他使用一個沉悶的黃油刀,而不是scalpell – Gordon 2011-03-12 17:32:34

+0

@Gordon的:它的工作原理呢。 – yoda 2011-03-12 17:33:26

回答

3

這是你的上一層>負荷問題,請嘗試

$template->loadHTMLFile("template/template.tpl"); 

但是你可能需要給它一個.html擴展名。

這是尋找一個html或xml文件。另外,無論何時使用HTML使用DOMDocument,在加載調用之前使用libxml_use_internal_errors(true);是個好主意。

OKAY這個工程:

foreach($template->getElementsByTagName("include") as $include) { 
    if ($include->hasAttributes()) { 
    $includes[] = $include; 
    } 
    //var_dump($includes); 
} 
foreach ($includes as $include) { 
      $include_name = $include->getAttribute("name"); 
     $input = $template->createElement('input'); 
$type = $template->createAttribute('type'); 
$typeval = $template->createTextNode('text'); 
$type->appendChild($typeval); 
$input->appendChild($type); 
$name = $template->createAttribute('name'); 
$nameval = $template->createTextNode('the_name'); 
$name->appendChild($nameval); 
$input->appendChild($name); 
$value = $template->createAttribute('value'); 
$valueval = $template->createTextNode($include_name); 
$value->appendChild($valueval); 
$input->appendChild($value); 
if ($include->getAttribute("name") == "head") { 
     $template->getElementsByTagName('head')->item(0)->replaceChild($input,$include); 
} 
else { 
     $template->getElementsByTagName("body")->item(0)->replaceChild($input,$include); 
} 
     } 
     //$template->load($nht); 
     echo $template->saveHTML(); 
+0

啊,所有這些想法都會很好,謝謝,但是他們都沒有工作。如果你可以看看,我已經編輯了一個更新的原始問題?基本上,而不是$ template-> replaceChild我使用$ include-> parentNode-> replaceChild它的工作原理,但只改變1個搜索實例。任何想法爲什麼? – 2011-03-12 17:53:55

+0

@Thomas我發佈了一個可行的更新,但我也同意Bobince的觀點,有很多更好的方法可以實現你正在努力實現的目標。 – 2011-03-12 22:55:30

1

但是似乎只改變1個occurence在我的HTML的...當我有三:/

DOM的NodeLists是'生活':當你從文檔中刪除一個<include>元素(通過替換它),它從列表中消失。相反,如果您將新的<include>添加到文檔中,它將出現在您的列表中。

對於來自元素的childNodes的NodeList,您可能會期望得到此結果,但返回getElementsByTagName的NodeLists也是如此。它是W3C DOM標準的一部分,併發生在Web瀏覽器的DOM以及PHP的DOMDocument中。

所以你在這裏是一個破壞性的迭代。刪除第一個<include>(列表中的項目0),第二個<include>(之前的項目1)成爲新的項目0.現在,當您移動到列表中的下一個項目時,項目1過去是項目2,導致你只看一半的項目。

PHP的foreach循環看起來像它可能會保護你,但實際上在它下面它做的和傳統索引for循環完全一樣。

我會盡量避免爲PHP創建新的模板語言;已經有很多了,更不用說PHP本身了。從DOMDocument創建一個也會特別慢。

eta:假如一個簡單的匹配模式不會引入回溯負載,那麼一般情況下,正則表達式替換會更快。但是,如果你使用XML語法,那麼正則表達式並不擅長解析它。但是,你試圖做什麼,用PHP不能完成?

<?php function write_header() { ?> 
    <p>This is the header bit!</p> 
<? } ?> 

<body> 
    ... 
    <?php write_header(); ?> 
    ... 
</body> 
+0

@ thomas-clayson我同意,雖然我的更新回答如下,但您在DomDocument中討論的這些內容所需的代碼量很快就會變得荒謬可笑。如果我必須自己創建模板,則使用SECTION_NAME,然後使用$ template = str_replace(「SECTION_NAME」,$ replacement,$ template); – 2011-03-12 21:21:49

+0

您好bobince,我沒有真的想創建一個模板語言,只是一個快速簡單的方法,使網站不涉及每次大的代碼更改!利亞姆,會preg_replace_callback比使用dom文件更快? – 2011-03-13 12:43:05

+0

@ thomas:添加示例。 – bobince 2011-03-13 12:58:47

相關問題