0

I am really confused with why this is happening have spent (quite a lot of time, more than I would like to admit). Basically when it gets to Date it does not add the date to the array whereas Time is absolutely fine.

XML Code Example

<xml>
<Route id="1">
    <itdDateTime>
        <itdDate day="28" month="10" year="2012" weekday="-1"/>
        <itdTime hour="12" minute="53"/>
    </itdDateTime>
</Route>
<Route id="2">
    <itdDateTime>
        <itdDate day="3" month="12" year="2012" weekday="-1"/>
        <itdTime hour="8" minute="14"/>
    </itdDateTime>
</Route>
<Route id="3">
    <itdDateTime>
        <itdDate day="3" month="12" year="2012" weekday="-1"/>
        <itdTime hour="9" minute="16"/>
    </itdDateTime>
</Route>

PHP Code Example

foreach($route->childNodes as $node) {
    if ($node->nodeName == 'itdDateTime') {
        foreach ($node->childNodes as $child) {
            $dateAttr = $child->attributes;
            $x[$i]['leave'] = array();
            $x[$i]['leave']['date'] = array();
            $x[$i]['leave']['time'] = array();
            foreach ($dateAttr as $index=>$attr) {
                $x[$i][$attr->nodeName] = $attr->nodeValue;             
                if ($index == 'minute' || $index == 'hour') {
                    $x[$i]['leave']['time'][$attr->nodeName] = $attr->nodeValue;
                } else {
                    $x[$i]['leave']['date'][$attr->nodeName] = $attr->nodeValue;
                }
            }
        }
    }
}

Array example

    Array
(
    [0] => Array
        (
            [active] => 1
            [delete] => 0
            [changes] => 2
            [distance] => 966
            [alternative] => 0
            [publicDuration] => 01:19
            [individualDuration] => 00:22
            [print] => 0
            [routeIndex] => 1
            [hasFrequency] => 1
            [routeTripIndex] => 1
            [cTime] => 20121028113640847
            [searchMode] => 1
            [vehicleTime] => 53
            [method] => itp
            [selected] => 1
            [leave] => Array
                (
                    [date] => Array
                        (
                        )

                    [time] => Array
                        (
                            [hour] => 12
                            [minute] => 53
                        )

                )

            [day] => 28
            [month] => 10
            [year] => 2012
            [weekday] => 1
            [hour] => 12
            [minute] => 53
        )

Problem

So basically the issue is that the date (day, month, weekday) should be entered into [leave][date] .. (example) [leave][date][day]

Even having no IF Statement, and entering it into [leave] array only doesnt work for example

$x[$i]['leave'][$attr->nodeName] = $attr->nodeValue;

So Im basically unsure and dont understand why it will show in the first array (such as next to Leave as per the example)

$x[$i][$attr->nodeName] = $attr->nodeValue;

Any advice or help on this would be greatly appreciated.

10
  • why do you need that in an array at all? why cant you just use the DOM Structure? Commented Oct 28, 2012 at 12:11
  • @Gordon it's OK, because it's be better to parse DOM only once and cache the array, then parse XML every time. Commented Oct 28, 2012 at 12:18
  • well Im wanting to turn the XML into JSON so I am first stripping the XMl out (the xml file itself is massive and has a lot of extra information i dont need. Commented Oct 28, 2012 at 12:26
  • @Hast just that the actual parsing into a DOM Tree happens only once when you load the XML, so that argument is kinda moot. Transforming the DOM Tree into a multi-dimensional array is just transforming the in-memory representation of the XML from one data structure to another. It's pointless. Commented Oct 28, 2012 at 12:27
  • @Gordon why? A large XML file could slow an execution. Should we parse it every time? I don't think so. Commented Oct 28, 2012 at 12:30

1 Answer 1

1
foreach ($node->childNodes as $child) {
    ...
    $x[$i]['leave'] = array();
    $x[$i]['leave']['date'] = array();
    $x[$i]['leave']['time'] = array();
    ...
}

This loop runs twice, for itdDate and itdTime, and as you can see on second iteration it is overwriting previously filled array with empty one.

You should check if these arrays does not exist before overwriting them, or better move their definition before looping through itdDateTime child nodes:

if ($node->nodeName == 'itdDateTime') {
    $x[$i]['leave'] = array();
    $x[$i]['leave']['date'] = array();
    $x[$i]['leave']['time'] = array();
    foreach ($node->childNodes as $child) {
        $dateAttr = $child->attributes;
        foreach ($dateAttr as $index=>$attr) {
            $x[$i][$attr->nodeName] = $attr->nodeValue;             
            if ($index == 'minute' || $index == 'hour') {
                $x[$i]['leave']['time'][$attr->nodeName] = $attr->nodeValue;
            } else {
                $x[$i]['leave']['date'][$attr->nodeName] = $attr->nodeValue;
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I see but does this not get sorted with the IF Statement? or am I missing something with that then
It doesn't run twice. As I can see, there is only one $i = 0. Even so, time would been either overwritten in that case.
@NickWhite you don't have if statement around it, add if(!isset($x[$i]['leave'])){ } around these array definitions and it will solve your problem

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.