如何更新使用数组的SimpleXMLElement [英] How to update SimpleXMLElement using array
问题描述
我有这样的XML为Flash恩codeR作品:
I have this xml that works for Flash Encoder:
<?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类型的数据。所以,我想要做这样的事情:
And I need to update some of the data depending on the type of xml the user requires. So I want to do something like this:
$data = array (
'preset' => array (
'name' => 'Low Bandwidth (150 Kbps) - H.264',
),
'capture' => array (
'audio' => array (
'sample_rate' => 44100
)
),
'encode' => array (
'video' => array (
'datarate' => '300;',
'outputsize' => '480x360;',
'advanced' => array (
'profile' => 'Main',
'level' => 2.1,
)
),
'audio' => array (
'datarate' => 48
)
),
);
我知道这棵树的作品,因为我可以做手工,但问题是,我不想那样做,所以如果将来我需要改变其他觉得在XML中,我只有将其添加到阵列配置。
I know this tree works, cause I can do it manually, but the problem is that I don't want to do it like that, so if in the future I need to change other think in the xml, I have only to add it to the array configuration.
我该怎么办呢?我可以写一个递归函数来做到这一点,但我真的不希望做的那样。是否有任何其他方式做到这一点?我不知道......可能是这样的:
How can I do it? I can write a recursive function to do it, but I don't really want to do it in that way. Is there any other way to do it? I don't know... may be something like:
$xml->updateFromArray($data);
由于我再说一遍,我可以编写功能和扩展的SimpleXMLElement,但如果有任何其他本机PHP的方法做它,它会更好。
As I repeat, I can write that function and extend SimpleXMLElement, but if there is any other native php method to do it, it will be better.
推荐答案
考虑 $ XML
是文档元素为的SimpleXMLElement
和 $数据
是阵列(如问题),如果你担心孩子的编号,例如:元数据,我把它在阵列中的编号是这样的:
Considering $xml
is the document element as a SimpleXMLElement
and $data
is your array (as in the question), if you are concerned about numbering children, e.g. for metadata, I have it numbered in the array this way:
'metadata' => array(
'entry' => array(
5 => array(
'value' => 'Sunny Days',
),
),
),
下面显示了如何用栈的帮助来解决问题以非递归的方式:
The following shows how to solve the problem in a non-recursive manner with the help of a stack:
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);
}
}
一些注意事项:
- 我改变了具体的异常类型删除的依赖。
-
$父[0] == NULL
测试元素$父
不为空(比较/见< A HREF =http://stackoverflow.com/a/14829309/367456> SimpleXML的类型的cheatsheet )。 - 作为元素节点放入堆栈供日后提取,
$节点[0]
需要被用来设置后,它从堆栈中取出(编号的元素已经在$节点
(默认为第一个),后来去改变它,数0
需要被用作偏移)。
- I changed the concrete exception type to remove the dependency.
$parent[0] == NULL
tests the element$parent
is not empty (compare/see SimpleXML Type Cheatsheet).- As the element node is put into the stack to be retrieved later,
$node[0]
needs to be used to set it after it got fetched from the stack (the numbered element is already in$node
(the first one by default), to change it later, the number0
needs to be used as offset).
而在线演示。
这个例子至今不允许,如果没有,到目前为止它们存在创造新的元素。要添加新的元素中加入抛出不存在的儿童除外:
The example so far does not allow to create new elements if they do not exist so far. To add adding of new elements the exception thrown for nonexisting children:
if ($parent[0] == NULL) {
throw new Exception(sprintf("Child-Element '%s' not found.", $element));
}
需要用一些code,它是将新的儿童,包括第一个被替换:
needs to be replaced with some code that is adding new children including the first one:
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);
}
}
的异常仍然在为的情况下,当添加新的元素,但它的数量比元件加一的现有数大。例如你有4个元素,然后是添加与6号元素,这是不行的。该值是零基础,这通常应该是没有什么问题的。
The exception still in is for the case when a new element is added but it's number is larger than the existing number of elements plus one. e.g. you have got 4 elements and then you "add" the element with the number 6, this won't work. The value is zero-based and this normally should not be any problem.
这篇关于如何更新使用数组的SimpleXMLElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!