我通过像这样的json字符串将XML文档解码为数组:
$xmldoc =
'<music genre="electronic">
<festival name="Berlin">
<concert status="Not Started" date="24.03.2017">
<organizers>
<person name="V. Smith" id="130171"/>
</organizers>
</concert>
</festival>
</music>';
$xml = simplexml_load_string($xmldoc);
$json = preg_replace_callback('/\\\\u([0-9a-f]{4})/i', 'replace_unicode_escape_sequence',json_encode($xml,true));
$array = json_decode($json,TRUE);
但是,具有属性的元素是使用另一个&#34; @ attributes&#34;创建的。像这样的层:
Array
(
[@attributes] => Array
(
[genre] => electronic
)
[festival] => Array
(
[@attributes] => Array
(
[name] => Berlin
)
[concert] => Array
(
[@attributes] => Array
(
[status] => Not Started
[date] => 24.03.2017
)
[organizers] => Array
(
[person] => Array
(
[@attributes] => Array
(
[name] => V. Smith
[id] => 130171
)
)
)
)
)
)
如何删除&#34; @属性&#34;图层,以便生成的数组看起来像这样:
Array
(
[genre] => electronic
[festival] => Array
(
[name] => Berlin
[concert] => Array
(
[status] => Not Started
[date] => 24.03.2017
[organizers] => Array
(
[person] => Array
(
[name] => V. Smith
[id] => 130171
)
)
)
)
)
我尝试递归遍历数组,我可以找到&#34; @属性&#34;,但是我很难将该部分移动一维以摆脱&#34; @属性&#34;层。 谢谢。
答案 0 :(得分:1)
尝试以下解决方案:
<?php
$xmldoc =
'<music genre="electronic">
<festival name="Berlin">
<concert status="Not Started" date="24.03.2017">
<organizers>
<person name="V. Smith" id="130171"/>
</organizers>
</concert>
</festival>
</music>';
$xml = simplexml_load_string($xmldoc);
$json = preg_replace_callback('/\\\\u([0-9a-f]{4})/i', 'replace_unicode_escape_sequence',json_encode($xml,true));
$array = json_decode($json,TRUE);
function removeSpecificKey(&$desired_array, $actualArray, $key_to_remove)
{
if (is_array($actualArray)) {
foreach ($actualArray as $key => $map) {
if ($key !== $key_to_remove) {
$desired_array[$key] = array();
removeSpecificKey($desired_array[$key], $actualArray[$key], $key_to_remove);
} else {
removeSpecificKey($desired_array, $actualArray[$key], $key_to_remove);
}
}
} else {
$desired_array = $actualArray;
}
}
$desired_array = array();
removeSpecificKey($desired_array, $array, '@attributes');
print_r($desired_array);
<强>输出:强>
Array
(
[genre] => electronic
[festival] => Array
(
[name] => Berlin
[concert] => Array
(
[status] => Not Started
[date] => 24.03.2017
[organizers] => Array
(
[person] => Array
(
[name] => V. Smith
[id] => 130171
)
)
)
)
)
答案 1 :(得分:0)
我首先要告诉你我对每个人使用越来越复杂的滥用SimpleXML和json_encode
的方式说的话 - 你为什么需要这个? Take退一步,考虑一下你将要使用这个数组,以及为什么你不能只使用SimpleXML本身。请查看the examples in the manual,了解具体方法。
例如,您想列出每个节日的组织者吗?然后你就这样循环:
$xmldoc =
'<music genre="electronic">
<festival name="Berlin">
<concert status="Not Started" date="24.03.2017">
<organizers>
<person name="V. Smith" id="130171"/>
</organizers>
</concert>
</festival>
</music>';
$xml = simplexml_load_string($xmldoc);
foreach ( $xml->festival as $festival ) {
echo '<h2>', (string)$festival['name'], '</h2>';
echo '<ul>';
foreach ( $festival->concert as $concert ) {
foreach ( $concert->organizers->person as $organizer ) {
echo '<li>', (string)$organizer['name'], '</li>';
}
}
}
如果你仍然认为抛出一半XML结构的数组就是你想要的,那么使用SimpleXML来创建它:
function turn_simplexml_into_broken_array($element) {
// Handle elements with text content
// By the way, this will break if the element has text content
// as well as children or attributes. So will the JSON hack.
// Because XML doesn't fit neatly in an array.
$text_content = trim( (string)$element );
if ( strlen($text_content) > 0 ) {
return $text_content;
}
$array = [];
foreach ( $element->attributes() as $name => $value ) {
$array[$name] = (string)$value;
}
foreach ( $element->children() as $name => $value ) {
// Handle multiple child elements with the same name
// Of course, this means the structure will be different
// for concerts with one organizer that concerts with multiple
// which leaving the object as SimpleXML would have saved you from
if ( count($element->{$name}) > 1 ) {
$array[$name][] = turn_simplexml_into_broken_array($value);
}
else {
$array[$name] = turn_simplexml_into_broken_array($value);
}
}
return $array;
}
$xml = simplexml_load_string($xmldoc);
print_r(turn_simplexml_into_broken_array($xml));
请注意,我们没有&#34;删除@ attributes&#34;这里。我们将XML属性与子元素一起放入数组中。
显然,你可以解决这个问题,以便更好地适应你正在使用的特定XML以及你想要的结构。在这一点上,再次问自己为什么你需要一个通用的功能。