【发布时间】:2014-04-07 11:15:42
【问题描述】:
对于一个项目,我正在解析和合并多个 xml 配置文件。这些 xml 配置定义了可能会或可能不会创建输出的块、在整个系统中可用的选项等。这些块是分层的,这意味着:一个块可以容纳其他块。
(合并的)配置可能如下所示:
<block name="root">
<block name="sub">
<block name="sub2">
<option name="some-option" value="some-value" />
</block>
<option name="sub" value="value" />
</block>
<option name="key" value="value" />
<remove name="sub" />
</block>
如您所见,块具有范围。这意味着:块sub 仅在块root 中可用,块sub2 仅在块sub 中可用。 但是:选项在任何地方都可用,但只有在包含块仍然存在时。如您所见,最后一行包含一个remove 'command',它从树中删除块sub,以及它的子块(块sub2 和选项some-option 和sub)。
如何维护分层对象结构并保持对元素范围的引用?
我探索了一些选项,例如分层对象结构:
class Block {
private $parent = null; // reference to parent block, or 'null' if no parent exists
private $children = array(); // list of children blocks
private $options = array(); // list of options
private $removes = array(); // list of remove 'commands'
}
甚至是嵌套集模型(具有左右值的 sql 模式)。
但无论我尝试什么,仍然会出现一些问题:
- “暂存”:如何在“全局范围”中提供可用选项、删除等,但要跟踪它们的定义位置。例如:名称为“some-option”的选项应该可用于系统的任何部分,除非它包含的块(“sub2”)被删除。
- “堆叠”:我需要存储所有“删除”选项,直到整个 xml 树被解析,然后才应该执行所有删除。移除应该从外到内执行。这意味着如果在高级块(更靠近根)中找到删除,则应首先执行它,也许从较低级块中删除删除指令。我有哪些选择?对于每个删除存储,引用它的持有块(例如
$remove[] = array('what-to-remove' => 'sub2', 'parent' => &$sub))?
我希望有人能指出我正确的方向!如果有不清楚的地方,请评论!
【问题讨论】:
-
remove是否意味着在解析 xml 时应该忽略sub或者应该在运行时将其删除?如果是后者,实际上什么时候应该删除? -
因为它是一个合并树,解析不能以线性方式完成,因为像
remove这样的指令几乎可以放置在任何地方,例如。在开始时(当尚未定义要删除的对象时)。而且,一些指令对“全局”范围有影响,其他指令只对它的包含块有影响。因此,删除block可能会导致删除remove(当它存在时,它又会删除另一个块)。 -
所以是的:虽然树应该尽可能早地被解析,但它应该在可能的最晚时刻被执行,以确保每个可能影响另一个指令的指令都已经可用。