解析文件中的嵌套标记
题
我想知道 - 解析类似内容的最有效方法是什么:
{{HEADER}}
Hello my name is {{NAME}}
{{#CONTENT}}
This is the content ...
{{#PERSONS}}
<p>My name is {{NAME}}.</p>
{{/PERSONS}}
{{/CONTENT}}
{{FOOTER}}
当然,这最终有点像一个模板系统,所以我的计划是创建一个“遍历”的散列图。模板,就像这样
$hash = array(
'HEADER' => 'This is a header',
'NAME' => 'David',
'CONTENT' => array('PERSONS' => array(array('NAME' => 'Heino'), array('NAME' => 'Sebastian')),
'FOOTER' => 'This is the footer'
);
值得注意的是“部分”。 (以#开头的标签),可以重复多次,我认为这就是让我失望的原因......
此外,任何部分都可以包含任意数量的其他部分和常规标记...
那么..你怎么做的?
解决方案
预期的输出是这样的:
这是一个标题
您好,我的名字是David
This is the content ...
My name is Heino.
My name is Sebastian.
这是页脚
如何管理哈希映射中嵌套数组与模板中可重复部分的关系?该模板的实际行为应该是什么?如果为非节元素提供了数组,它会做什么?如果为一个section元素提供一个单独的值,它是否会被视为只有一个元素的数组(我假设如此)?
无论如何,关于模板的解析器(无论你最终用数据映射做什么)......我要做的是为每种类型的令牌创建一个类,包括非泛型的一个类 - 说出内容。这些将继承自具有可覆盖的Parse,Render和Map方法的公共令牌基类。
绘制您的状态图并找出每个状态的入口和出口点,然后将其编码到令牌之间的调用结构中。最后,您希望生成描述模板的可枚举标记集合。
一旦你以抽象形式获得它,你可以遍历在令牌上调用Map的集合,将数据从hashmap分配给标记,然后调用Render将模板渲染到它的最终形式。
希望有所帮助。
其他提示
最有效的方法是编译模板到php代码。只需包含编译版本。
Smarty模板引擎做了类似的事情。您还可以查看smarty源并检查它们如何解析标记。
我会选择第三方解析器,因为我喜欢更聪明,更努力地工作,但是如果你正在做这个练习,或者你真的想要构建自己的模板引擎(在PHP中,我假设因为标签),我将首先回顾一下设计模式,复合设计模式。
复合模式在Java框架中经常用于这样的事情,包括XML解析。
我会在.php单独的文件中使用这样的东西:
<?php echo $HEADER ?>
Hello my name is <?php echo $NAME?>
<div id="CONTENT">
This is the content ...
<?php foreach ($PERSONS as $PERSON) : ?>
<p>My name is <?php echo $PERSON['NAME']?>.</p>
<?php endforeach ?>
</div>
<?php echo $FOOTER ?>
只需将上面的文件包含在填充引用变量的文件中即可。
信不信由你,PHP已经提供了模板系统声称要实现的所有功能。没有必要在PHP之上添加另一层抽象(和复杂性)。
我使用 PHP的DOM 。我的模板语言只是带有ID和类属性的HTML。但是,如果你想坚持你的计划,我会使用 preg_replace_callback ,其模式与你的语法和一个回调函数,它在哈希中找到适当的替换,在容器元素上递归调用它自己。