简体   繁体   English

未捕获的异常'DOMException',消息'Not Found Error'

[英]Uncaught exception 'DOMException' with message 'Not Found Error'

Bascially I'm writing a templating system for my CMS and I want to have a modular structure which involves people putting in tags like: 基本上我正在为我的CMS编写一个模板系统,我想要一个模块化的结构,让人们输入标签,如:

<module name="news" /> or <include name="anotherTemplateFile" /> which I then want to find in my php and replace with dynamic html. <module name="news" /><include name="anotherTemplateFile" />然后我想在我的php中找到并用动态html替换。

Someone on here pointed me towards DOMDocument, but I've already come across a problem. 有人在这里向我指出DOMDocument,但我已经遇到了一个问题。

I'm trying to find all <include /> tags in my template and replace them with some simple html. 我正在尝试在我的模板中找到所有<include />标签,并用一些简单的html替换它们。 Here is my template code: 这是我的模板代码:

<!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>

And here is my PHP: 这是我的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();

Now, I get the fatal error Uncaught exception 'DOMException' with message 'Not Found Error' . 现在,我收到致命错误Uncaught exception 'DOMException' with message 'Not Found Error'

I've looked this up and it seems to be that because my <include /> tags aren't necessarily DIRECT children of $template its not replacing them. 我看了这个,似乎是因为我的<include />标签不一定是$template DIRECT孩子,而不是替换它们。

How can I replace them independently of descent? 我怎样才能独立于血统替换它们?

Thank you 谢谢

Tom 汤姆

EDIT 编辑

Basically I had a brainwave of sorts. 基本上我有各种各样的脑波。 If I do something like this for my PHP I see its trying to do what I want it to do: 如果我为我的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();

However it only seems to change 1 occurence in the <body> of my HTML... when I have 3. :/ 然而它似乎只改变我的HTML的<body>的1个出现...当我有3.:/

This is a problem with your DOMDocument->load, try 这是DOMDocument-> load的问题,请尝试

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

But you may need to give it a .html extension. 但是你可能需要给它一个.html扩展名。

this is looking for a html or an xml file. 这是在寻找一个html或xml文件。 also, whenever you are using DOMDocument with html it is a good idea to use libxml_use_internal_errors(true); 另外,每当你使用带有html的DOMDocument时,最好使用libxml_use_internal_errors(true); before the load call. 在加载调用之前。

OKAY THIS WORKS: 好的,这个工作:

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();

However it only seems to change 1 occurence in the of my HTML... when I have 3. :/ 然而它似乎只改变了我的HTML中的1个出现...当我有3.:/

DOM NodeLists are 'live': when you remove an <include> element from the document (by replacing it), it disappears from the list. DOM NodeLists是“实时”:当您从文档中删除<include>元素(通过替换它)时,它将从列表中消失。 Conversely if you add a new <include> into the document, it will appear in your list. 相反,如果您在文档中添加新的<include> ,它将显示在您的列表中。

You might expect this for a NodeList that comes from an element's childNodes , but the same is true of NodeLists that are returned getElementsByTagName . 对于来自元素的childNodes的NodeList,您可能会期望这样,但返回getElementsByTagName的NodeLists也是如此。 It's part of the W3C DOM standard and occurs in web browsers' DOMs as well as PHP's DOMDocument. 它是W3C DOM标准的一部分,发生在Web浏览器的DOM以及PHP的DOMDocument中。

So what you have here is a destructive iteration. 所以你在这里有一个破坏性的迭代。 Remove the first <include> (item 0 in the list) and the second <include> , previously item 1, become the new item 0. Now when you move on to the next item in the list, item 1 is what used to be item 2, causing you to only look at half the items. 删除第一个<include> (列表中的项目0),第二个<include> ,先前的项目1,成为新项目0.现在当您转到列表中的下一个项目时,项目1是以前的项目第2项,导致你只看一半的项目。

PHP's foreach loop looks like it might protect you from that, but actually under the covers it's doing exactly the same as a traditional indexed for loop. PHP的foreach循环看起来像它可以保护您从,但实际上在幕后它做完全一样的传统索引for循环。

I'd try to avoid creating a new templating language for PHP; 我会尽量避免为PHP创建一个新的模板语言; there are already so many, not to mention PHP itself. 已经有这么多了,更不用说PHP本身了。 Creating one out of DOMDocument is also going to be especially slow. 用DOMDocument创建一个也会特别慢。

eta: In general regex replace would be faster, assuming a simple match pattern that doesn't introduce loads of backtracking. eta:一般来说,正则表达式替换会更快,假设一个简单的匹配模式不会引入回溯负载。 However if you are wedded to an XML syntax, regex isn't very good at parsing that. 但是,如果您坚持使用XML语法,那么正则表达式在解析它时并不是很好。 But what are you attempting to do, that can't already be done with PHP? 但是你想做什么,用PHP已经不能做了?

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 PHP DOMDocument编写站点地图问题-未捕获的异常&#39;DOMException&#39; - PHP DOMDocument Writing Sitemap Problems - Uncaught exception 'DOMException' PHP DOMElement appendChild get DOMException错误的文档错误 - PHP DOMElement appendChild get DOMException Wrong Document Error 未捕获错误:未找到“Google \\ AdsApi \\ Examples \\ Class \\ AdWords \\ v201809 \\ Reporting \\ DOMDocument”类 - Uncaught Error: Class 'Google\AdsApi\Examples\AdWords\v201809\Reporting\DOMDocument' not found 获取无效字符 DOMException 错误。 我已经实现了 htmlentities 来更改特殊字符,但没有运气 - Getting an invalid character DOMException error. I've implemented htmlentities to change special characters but no luck php DOMDocument removeChild 抛出未找到异常 - php DOMDocument removeChild throws exception of not found 错误:找不到类“ DOMDocument” - ERROR: Class 'DOMDocument' not found XML解析错误…未找到元素 - XML Parsing Error… No Element Found PHP DOMDocument insertBefore引发“未找到错误” - PHP DOMDocument insertBefore throws “Not Found Error” 致命错误:找不到类&#39;DOMDocument&#39;,在我的PHP版本5.2.16中 - Fatal error: Class 'DOMDocument' not found and in my PHP Version 5.2.16 致命错误:Zend Server CE更新后找不到DOMDocument - Fatal Error: DOMDocument not found after Zend Server CE Update
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM