在多维数组中移动元素

时间:2017-03-24 09:44:32

标签: php arrays json xml simplexml

我通过像这样的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;层。 谢谢。

2 个答案:

答案 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以及你想要的结构。在这一点上,再次问自己为什么你需要一个通用的功能。