Преобразование XML в массив пропускает некоторую информацию из строки XML

Я использую curl, чтобы получить внешний XML-документ и преобразовать его в массив.

Код работает почти идеально, за исключением того, что один узел в XML не обрабатывается и не помещается в мой массив.

Под <drivers> есть код для каждого драйвера: <driver code="TM1"> но это не воспринимается моим массивом как массив @attribute, как и другие, такие как <collection date="20160324">

Кто-нибудь знает, почему это происходит?

XML:

<findit xmlns="http://www.URL.COM" version="8" type="TIX" date="20160323">
<account code="XXXXXX">
<customers>
<customer code="12345">
<status code="0">Success</status>
<logistic-jobs>
<logistic-job id="12345" date="20160324" status="PLA" modified="201603231420">
<number>
<number1>479599</number1>
<number3>11221</number3>
</number>
<collection date="20160324" time="0500">
<name>JOHN SMITH</name>
<address1>UNIT 3 DAVEY ROAD</address1>
<address2>FIELDS END BUSINESS PARK</address2>
<address3>GOLDTHORPE</address3>
<address4>ROTHERHAM</address4>
<address5>S63 0JF</address5>
</collection>
<delivery date="20160324" time="1200">
<address1>EXAMPLE</address1>
<address2>GLENEAFLES FARM</address2>
<address3>GLENEAGLES CLOSE</address3>
<address4>STANWELL, MIDDLESEX</address4>
<address5>TW19 7PD</address5>
</delivery>
<extra>
<address1>45FT C/SIDER</address1>
<address2>No</address2>
<address4>CEMENT</address4>
</extra>
<drivers>
<driver code="TM1">DAVE SMITH (DAYS)</driver>
</drivers>
<load weight="27600.00" volume="0.00">
<pallets full="23" half="0" quarter="0" blue="0" oversize="0"/>
</load>
</logistic-job>
</logistic-jobs>
</customer>
</customers>
</account>
</findit>

PHP:

$job_array = json_decode(json_encode(simplexml_load_string($xml)), true);

if(is_array($job_array['account']['customers']['customer'])) {

// Foreach customer in array
foreach($job_array['account']['customers']['customer'] as $i => $customer) {

// If status is set to success
if($customer['status'] == "Success") {

// For each job
foreach($customer['logistic-jobs']['logistic-job'] as $i => $job) {

echo '<pre>'; print_r($job); echo '</pre>';

}

}

}

}

ВЫХОД:

Array
(
[@attributes] => Array
(
[id] => 12345
[date] => 20160324
[status] => PLA
[modified] => 201603231420
)

[number] => Array
(
[number1] => 479599
[number3] => 11221
)

[collection] => Array
(
[@attributes] => Array
(
[date] => 20160324
[time] => 0500
)

[name] => JOHN SMITH
[address1] => UNIT 3 DAVEY ROAD
[address2] => FIELDS END BUSINESS PARK
[address3] => GOLDTHORPE
[address4] => ROTHERHAM
[address5] => S63 0JF
)

[delivery] => Array
(
[@attributes] => Array
(
[date] => 20160324
[time] => 1200
)

[address1] => EXAMPLE
[address2] => GLENEAFLES FARM
[address3] => GLENEAGLES CLOSE
[address4] => STANWELL, MIDDLESEX
[address5] = TW19 7PD
)

[extra] => Array
(
[address1] => 45FT C/SIDER
[address2] => No
[address4] => CEMENT
)

[drivers] => Array
(
[driver] => DAVE SMITH (DAYS)
)

[load] => Array
(
[@attributes] => Array
(
[weight] => 21509.00
[volume] => 0.00
)

[pallets] => Array
(
[@attributes] => Array
(
[full] => 52
[half] => 0
[quarter] => 0
[blue] => 0
[oversize] => 0
)

)

)

)

0

Решение

У меня есть простой ответ для вас: не конвертируйте XML в массив. SimpleXML имеет действительно полезный API для просмотра XML-документа и поиска нужных данных; выбросить ужасное json_decode(json_encode( взломать и посмотреть на примеры в руководстве по PHP.

В этом случае, echo $driver даст вам содержимое (имя водителя) и echo $driver['code'] даст вам значение атрибута; ясно, что у простого массива не может быть такой удобной магии, поэтому преобразование в один доставляет вам проблемы.

Просто запомни это print_r также будет скрывать вещи от вас, и вы можете захотеть выделенная функция отладки.

Вот пример (с живое демо) получения кода и имени каждого драйвера:

$job_simple = simplexml_load_string($xml);

if(isset($job_simple->account->customers->customer)) {

// Foreach customer in array
foreach($job_simple->account->customers->customer as $i => $customer) {

// If status is set to success
if((string)$customer->status == "Success") {

// For each job
foreach($customer->{'logistic-jobs'}->{'logistic-job'} as $i => $job) {
echo "<ul>\n";
foreach ( $job->drivers->driver as $driver ) {
echo "<li> {$driver['code']}: $driver\n";
}
echo "</ul>\n";
}
}
}
}
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]