使用PHP,我试图找到一种简单的方法来解析HTML文件,这些文件也包含非HTML内容,例如自定义标签和放大器。内联PHP代码段。我需要迎合的元素的一个例子如下:
<!DOCTYPE html>
<html [[angular tag 1]]>
<head <?php echo 'php snippet 1'; ?>>
<title {{curly tag 1}}></title>
<link [[angular tag 2]]="{{curly tag 2}}.css" />
<script src="<?php echo 'php snippet 2'; ?>.js"></script>
</head>
<body>
<?php echo 'php snippet 3'; ?>
<!-- comment 1 -->
[[angular tag 3]]
</body>
</html>
这只是一个简单的例子,另一个需要可能是处理部分HTML片段,这些片段不一定包括html,head&amp;身体标签。你可以看到标签&amp; PHP代码段可以在整个文档中的任何位置出现,只要它们正确嵌套在相关实体中:
我需要PHP代码片段卷曲“标签”&amp;角度“标签”要解析为令牌 - 它们不需要自己处理 - 解析后我需要这样做。我也在这个阶段没有看到需要在自己内部或在PHP代码片段内满足嵌套标签。
理想情况下,我想找到一个库或至少一组已经实现了可以做到这一点的文件;而不是自己做。
据我所知DOMDocument&amp; SimpleXML不支持格式错误的XML语法或外来元素,因此除非我删除自定义标记和放大,否则它们不能用于处理它。 php代码然后重新插入;但这可能需要与滚动我自己的解析器一样多的工作。
警告:请保留关于在视图逻辑等中不包含php代码的评论。我知道这些设计原则。
答案 0 :(得分:2)
重要的是要了解仅仅存在<?php ?>
格式的代码段不会使您的代码无效。
SGML和XML都支持格式为<?PITarget PIContent?>
的任何标记,称为processing instructions。任何不知道如何处理处理指令的解析器都应该忽略它。例如,浏览器typically ignore any PHP code they find。
处理指令在文档对象模型中显示为Node.PROCESSING_INSTRUCTION_NODE
。如果您使用DOMDocument
在PHP中解析文档,则此类节点具有node type XML_PI_NODE
。您也可以使用DOMDocument
XPath command在processing-instruction()
找到它们。
如果您的代码是有效的HTML5但不是有效的XML,则可能需要尝试Masterminds/html5-php。我在PHPPowertools/DOM-Query的引擎盖下自己使用它。我不确定它对无效HTML5的效果如何,也不知道它对处理指令的作用。
答案 1 :(得分:1)
基于John's answer&amp;从Masterminds/html5-php给出的输出中得出的一些推论我发现使用DOMDocument时唯一真正的问题是我在html打开或关闭标签中使用PHP标签。即在<
&amp;之间>
个字符。事后看来,这一切都很有道理。
因此,实际阻止它正确解析的违规HTML模板的唯一部分是<head <?php echo 'php snippet 1'; ?>>
和<script src="<?php echo 'php snippet 2'; ?>.js">
,因为存在嵌套的角括号,这显然是基本上无效的HTML。
这意味着,只需更新HTML模板以在这些实例中使用自定义标记,就可以消除格式错误的输出和输出。关键的解析错误。这对我的需求来说是令人满意的。我实际上感觉更优雅,因为它不会在HTML模板中产生嵌套的尖括号 - 即使PHP解析器在处理PHP文件时处理它。
更新的可操作模板看起来像这样:
<!DOCTYPE html>
<html [[angular tag 1]]>
<head [[replaced PHP code snippet 1]]>
<title {{curly tag 1}}></title>
<link [[angular tag 2]]="{{curly tag 2}}.css" />
<script src="[[replaced PHP code snippet 2]].js"></script>
</head>
<body>
<?php echo 'php snippet 3'; ?>
<!-- comment 1 -->
[[angular tag 3]]
</body>
</html>
我用来测试的代码是:
switch(1) {
case 1: {
$log->info( 'Masterminds/html5-php' );
$html5 = new HTML5();
$dom = $html5->loadHTML( $szTemplate );
echo $html5->saveHTML( $dom );
exit;
}
case 2: {
$log->info( 'DOMDocument' );
$doc = new \DOMDocument();
$doc->loadHTML( $szTemplate );
echo $doc->saveHTML();
exit;
}
}
答案 2 :(得分:0)
如果要在PHP已经解析并发送输出后执行此操作。包含带有令牌的文件,并使用输出缓冲捕获已解析的HTML;然后解析剩余的标签。
当您在变量中捕获已解析的HTML时,您可以:
preg_match_all('#{{[[:alnum:]_]}}', $HTML, $curlies_found);
捕获令牌,然后替换与相应值匹配的令牌,例如通过循环匹配的令牌并替换$curly_tokens
数组中的键。
str_replace
覆盖所有令牌变量的HTML; str_replace('{{token_foo}}', $curly_tokens['token_foo'], $HTML);
。
对每种类型的令牌重复此过程。如果你有很多代码需要搜索和替换,第一种方法可能会更经济,所有这些代码都可能不在给定的模板中。如果您的模板中存在少量令牌,则第二个可能更快。
我认为你不需要一个库,几十行代码顶部足以完成令牌解析的基本实现。有关简单令牌解析的信息,请参阅my answer here。
如果您将HTML中的PHP代码段转换为代币,则可以使用file_get_contents
来获取HTML模板并解析代币,而不是摆弄include
并输出缓冲。但无论哪种方式最适合你,你的电话。