对于我正在解析和合并多个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
'命令',它会从树中移除块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模式)。
但无论我尝试什么,仍然会出现一些问题:
$remove[] = array('what-to-remove' => 'sub2', 'parent' => &$sub)
)?我希望有人能指出我正确的方向!如果不清楚,请发表评论!
答案 0 :(得分:0)
你可以使用一种Register类:
<?php
class Register {
protected static $_instance;
protected $_options = array();
public static function getInstance() {
if( null === self::$_instance ) {
self::$_instance = new Register();
}
return self::$_instance;
}
// Assuming your option has a unique name
public function registerOption( Option $option, Block $owner = null ) {
$this->_options[$option->name] = array(
'option' => $option,
'owner' => $owner
);
// Adds the option to the block if not exists
if( null !== $owner && !$owner->hasOption($option) ) {
$owner->addOption($option);
}
}
public function removeOption( $optionName, $removeFromOwner = true ) {
if( isset($this->_options[$optionName]) ) {
if( $removeFromOwner ) {
$owner = $this->_options[$optionName]['owner'];
if( null !== $owner ) {
$owner->removeOption( $optionName );
}
}
unset( $this->_options[$optionName] );
}
}
}
在块中解析新选项时,可以通过调用Register :: getInstance() - &gt; registerOption($ option,$ owner)来注册它
在解析XML时,可以将删除命令堆叠在包含要删除的选项名称的数组中(假设选项名称是唯一的,如果它们不是唯一的,您可能必须解决此解决方案。)< / p>
解析完所有内容后,您可以取消删除删除命令并调用removeOption($ optionName)以从寄存器和拥有该选项的块中删除该选项。
我忘记了什么吗?