1

I wrote a recursive function that is supposed to convert an xml into an associative array. The function I wrote so far worked with the root element containing 1 child only, however when I tried it on an xml which the root has more than 1 child, it only outputted the first child.

Here is the function I wrote: $values is the values array from xml_parse_into_struct.

    function _xml2array($append, $values, $i) {
    if($i == count($values) - 1) {
        return $append;
    }

    switch($values[$i]['type']) {
        case 'open':
            $tag = $values[$i]['tag'];
            $append[$tag][] = _xml2array($append[$tag], $values, ++$i);
            return $append;
        case 'complete':
            $tag = $values[$i]['tag'];
            $val = $values[$i]['value'];
            $append[$tag] = $val;
            return _xml2array($append, $values, ++$i);
        case 'close':
            return $append;
    }
}

function xml2array($values) {
    return _xml2array(array(), $values, 0);
}

And here is the xml I'm working on:

<?xml version="1.0"?>

<espadas>
    <espada>
        <name>Coyote Starrk</name>
        <rank>Primera</rank>
        <resurreccion>
            <release-command>Kick About</release-command>
            <zan-name>Los Lobos</zan-name>
        </resurreccion>
    </espada>
    <espada>
        <name>Baraggan Louisenbairn</name>
        <rank>Segunda</rank>
        <resurreccion>
            <release-command>Rot</release-command>
            <zan-name>Arrogante</zan-name>
        </resurreccion>
    </espada>
</espadas>

And here is the output I'm getting:

Array
(
    [ESPADAS] => Array
        (
            [0] => Array
                (
                    [ESPADA] => Array
                        (
                            [0] => Array
                                (
                                    [NAME] => Coyote Starrk
                                    [RANK] => Primera
                                    [RESURRECCION] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [RELEASE-COMMAND] => Kick About
                                                    [ZAN-NAME] => Los Lobos
                                                )

                                        )

                                )

                        )

                )

        )

)

What am I doing wrong that I'm only getting the first child? Any kind of help would be appreciated.

EDIT: Tried debugging again, and realized I need to put a base case. But that still leaves me with an array with the first child only.

1
  • I did not consider that, I could just drop the root element ESPADAS and have the root key as ESPADA and store each ESPADA in its current position Commented Sep 8, 2014 at 9:45

1 Answer 1

1

Your code has the expectation encoded that there is one child-element with the same tag-name.

$append[$tag] = _xml2array ...

This is a wrong expectation. XML can have 0-n child-element(s) with the same tag-name.

Therefore you need to encode the case, that there can be zero or more tagnames:

$append[$tag][] = _xml2array ...

As you also do the same mistake on the complete state, you need to modify your code there as well, which I leave as a trivial excercise to apply the given answer there, too.

Sign up to request clarification or add additional context in comments.

10 Comments

The ones in complete will appear only once, so can I leave them as is? And I added the change you wrote ...[$tag][] = ... it still only showed the first element.
I would treat all cases equal to keep complexity low. Otherwise you would need to think about each time which case you have and use different logic to deal with it. Next to that, if I may ask, what is wrong with the array that xml_parse_into_struct already returns?
And now as you comment it, you might also have a flaw when you pass $append[$tag] into _xml2array. I didn't highlight that part so far.
I want to show the array in a neat way, with only tag and value without other data like levels and type.
Where do you want to show it? If it's display only, you don't need to change the structure, just the way you print/display it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.