提问人:David 提问时间:10/18/2008 更新时间:10/18/2008 访问量:1541
解析文件中的嵌套标记
Parsing of nested tags in a file
问:
我想知道 - 解析类似内容的最有效方法是什么:
{{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'
);
值得注意的是,“部分”(以 # 开头的标签)可以重复不止一次,我认为这就是绊倒我的原因......
此外,任何部分都可以包含任意数量的其他部分和常规标签......
所以。。你是怎么做到的?
答:
你最好使用现有的解析器,如XML或JSON,这样你就不必编写自己的解析器,这样其他人就可以轻松地为你的解析器编写文档,而不需要专门的工具。但是,如果您想编写自己的解析器,您可能需要考虑使用 Lex 和 Yacc。
我会使用第三方解析器,因为我喜欢更聪明地工作,而不是更努力地工作,但如果你这样做是为了练习,或者你真的想构建自己的模板引擎(在PHP中,我假设是因为标签),我会从审查设计模式开始,特别是复合设计模式。
复合模式在 Java 框架中被大量用于此类操作,包括 XML 解析。
这个的预期输出是这样的吗:
这是一个标头
你好,我的名字是大卫
This is the content ...
My name is Heino.
My name is Sebastian.
这是页脚
您如何管理哈希映射中的嵌套数组与模板中可重复部分的关系?模板的实际行为应该是什么?如果为非 section 元素提供了数组,它将做什么?如果为一个 section 元素提供了一个值,它是否会被视为与只有一个元素的数组相同(我假设是这样)?
无论如何,关于模板的解析器(无论您最终对数据映射做什么)......我要做的是为每种类型的令牌创建一个类,包括一个用于非令牌内容的通用类。它们将继承自具有可重写的 Parse、Render 和 Map 方法的公共令牌基类。
绘制出状态图,并找出每个状态的进入点和退出点,然后将其编码到令牌之间的调用结构中。最后,您希望生成一个描述模板的可枚举标记集合。
以抽象形式获得它后,您可以迭代调用标记的集合,以将哈希映射中的数据分配给标记,然后调用 Render 将模板呈现为其最终形式。
希望能有所帮助。
评论
我会在 .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 和一个回调函数,该函数在您的哈希中找到适当的替换,在容器元素上递归调用自己。
评论
最有效的方法是将模板编译为 php 代码。并且只包括编译版本。
Smarty 模板引擎执行类似的操作。您还可以查看智能源并检查它们如何解析标签。
评论