2011-03-12 84 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

相关问题