Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用数组更新SimpleXMLElement_Php_Xml_Arrays_Simplexml - Fatal编程技术网

Php 如何使用数组更新SimpleXMLElement

Php 如何使用数组更新SimpleXMLElement,php,xml,arrays,simplexml,Php,Xml,Arrays,Simplexml,我有一个适用于Flash编码器的xml: <?xml version="1.0" encoding="UTF-8"?> <flashmedialiveencoder_profile> <preset> <name></name> <description></description> </preset> <capture>

我有一个适用于Flash编码器的xml:

<?xml version="1.0" encoding="UTF-8"?>
<flashmedialiveencoder_profile>
    <preset>
        <name></name>
        <description></description>
    </preset>
    <capture>
        <video>
            <device></device> 
            <crossbar_input>1</crossbar_input>
            <frame_rate>25.00</frame_rate>
            <size>
                <width></width>
                <height></height>
            </size>
        </video>
        <audio>
            <device></device> 
            <crossbar_input>2</crossbar_input>
            <sample_rate></sample_rate>
            <channels>1</channels>
            <input_volume>60</input_volume>
        </audio>
    </capture>
    <encode>
        <video>
            <format>H.264</format>
            <datarate></datarate>
            <outputsize></outputsize>
            <advanced>
                <profile></profile>
                <level></level>
                <keyframe_frequency>5 Seconds</keyframe_frequency>
            </advanced>
            <autoadjust>
                <enable>false</enable>
                <maxbuffersize>1</maxbuffersize>
                <dropframes>
                <enable>false</enable>
                </dropframes>
                <degradequality>
                <enable>false</enable>
                <minvideobitrate></minvideobitrate>
                <preservepfq>false</preservepfq>
                </degradequality>
            </autoadjust>
        </video>
        <audio>
            <format>MP3</format>
            <datarate></datarate>
        </audio>
    </encode>
    <restartinterval>
        <days></days>
        <hours></hours>
        <minutes></minutes>
    </restartinterval>
    <reconnectinterval>
        <attempts></attempts>
        <interval></interval>
    </reconnectinterval>
    <output>
        <rtmp>
        <url></url>
        <backup_url></backup_url>
        <stream></stream>
        </rtmp>
    </output>
    <metadata>
        <entry>
        <key>author</key>
        <value></value>
        </entry>
        <entry>
        <key>copyright</key>
        <value></value>
        </entry>
        <entry>
        <key>description</key>
        <value></value>
        </entry>
        <entry>
        <key>keywords</key>
        <value></value>
        </entry>
        <entry>
        <key>rating</key>
        <value></value>
        </entry>
        <entry>
        <key>title</key>
        <value></value>
        </entry>
    </metadata>
    <preview>
        <video>
        <input>
            <zoom>50%</zoom>
        </input>
        <output>
            <zoom>50%</zoom>
        </output>
        </video>
        <audio></audio>
    </preview>
    <log>
        <level>100</level>
        <directory></directory>
    </log>
</flashmedialiveencoder_profile>
我知道这棵树是有效的,因为我可以手动操作,但问题是我不想这样做,所以如果将来我需要改变xml中的其他想法,我只需要将它添加到阵列配置中

我怎么做?我可以编写一个递归函数来实现它,但我真的不想这样做。还有别的办法吗?我不知道。。。可能是这样的:

$xml->updateFromArray($data);

重复一遍,我可以编写该函数并扩展SimpleXMLElement,但如果有其他本机php方法来实现它,它会更好。

我已经将此对象扩展为SimpleXMLElement,但如果有更好的方法,我会非常感激:)


当对象
Stream\u simplexmlement
扩展
simplexmlement
时,对象的每个子对象都将是
Stream\u simplexmlement
的实例,因此,我们可以使用相同的方法…

考虑到
$xml
是作为
simplexmlement
的文档元素,
$data
是您的数组(如问题中所述),如果您关心子元素的编号,例如对于元数据,我在数组中按以下方式对其进行编号:

'metadata' => array(
    'entry' => array(
        5 => array(
            'value' => 'Sunny Days',
        ),
    ),
),
下面显示了如何借助堆栈以非递归方式解决问题:

while (list($set, $node) = array_pop($stack)) {
    if (!is_array($set)) {
        $node[0] = $set;
        continue;
    }

    foreach ($set as $element => $value) {
        $parent = $node->$element;
        if ($parent[0] == NULL) {
            throw new Exception(sprintf("Child-Element '%s' not found.", $element));
        }
        $stack[] = array($value, $parent);
    }
}
一些注意事项:

  • 我更改了具体的异常类型以删除依赖项
  • $parent[0]==NULL
    测试元素
    $parent
    是否为空(比较/查看)
  • 由于元素节点被放入堆栈中以供以后检索,因此从堆栈中获取后需要使用
    $node[0]
    对其进行设置(编号的元素已经在
    $node
    中(默认情况下是第一个),要在以后更改它,需要将编号
    0
    用作偏移量)
还有


到目前为止的示例不允许创建新元素(如果它们还不存在)。要添加新元素,请为不存在的子级引发异常:

        if ($parent[0] == NULL) {
            throw new Exception(sprintf("Child-Element '%s' not found.", $element));
        }
需要替换为添加新子项的一些代码,包括第一个:

        if ($parent[0] == NULL) {
            if (is_int($element)) {
                if ($element != $node->count()) {
                    throw new Exception(sprintf("Element Number out of order: %d unfitting for %d elements so far.", $element, $node->count()));
                }
                $node[] = '';
                $parent = $node->$element;
            } else {
                $parent[0] = $node->addChild($element);
            }
        }
仍然存在的例外情况是,添加了新元素,但其数量大于现有元素数量加上1。e、 g.你有4个元素,然后用数字6“添加”元素,这不起作用。该值是基于零的,这通常不会有任何问题


updateFromArray(array$array)方法有一个参数,但是,您可以用两个参数调用它。您可能需要查看。是的,我删除了seconde参数,但没有在调用中删除。我已经更新了这个方法,我不知道有什么本机PHP函数-有一些函数用于序列化,但这可能不像您所期望的那样具体。我也不清楚递归有什么问题。我倾向于避免递归性,因为如果使用不正确,它可能是有害的。而且,在大多数情况下,还有其他方法可以在没有递归性的情况下实现相同的结果。但是,我认为这不是其中之一……我只是更新了基于堆栈的方法,它不需要递归,而且它还显示了一些适合SimpleXML的语法-请参见注释。它现在也可以与编号元素一起使用,并且有一个在线演示来更轻松地使用它。您仍然可以从SimpleXMLElement进行扩展,并添加您自己的方法。@hakre只是为了添加更多的细节,这就是为什么我建议避免递归:vs这看起来太棒了!一个问题:我写的代码之间有什么区别?我愿意使用这个,但是我想知道这个和上面代码的区别…谢谢你!我选择这一个作为正确答案,因为它按照我的意愿工作,没有递归。老实说,我不清楚它是如何工作的,所以我会研究:)无论如何,非常感谢:)我有一个问题。如果要向数组中添加信息,该怎么办?例如,如果我想在条目中添加另一个数据。。。请参见此示例:标准的数组推送操作应该可以做到这一点:
$entry['metadata']['entry'][]=array('value'=>'New')-此处自动输入PHP数字。如果有疑问,请参阅并使用
print\u r
/
var\u dump
检查。问题不在于此。请看这个例子:我可以按照您的建议来做,但我不知道有多少元素是新的,也不知道哪些元素是新的,所以我需要以编程的方式来做。如果我可以编辑功能,你给我以前将是伟大的!(我已经试过了,但没能做到…)
        if ($parent[0] == NULL) {
            throw new Exception(sprintf("Child-Element '%s' not found.", $element));
        }
        if ($parent[0] == NULL) {
            if (is_int($element)) {
                if ($element != $node->count()) {
                    throw new Exception(sprintf("Element Number out of order: %d unfitting for %d elements so far.", $element, $node->count()));
                }
                $node[] = '';
                $parent = $node->$element;
            } else {
                $parent[0] = $node->addChild($element);
            }
        }