Сжатие массива при конвертации из SimpeXML - PullRequest
1 голос
/ 11 марта 2019

У меня есть следующая структура XML:

<?xml version="1.0" encoding="UTF-8"?>
<phonebooks>
    <phonebook owner="0" name="phonebook">
        <contact>
            <person>
                <realName>Name, Firstname</realName>
            </person>
            <telephony>
                <number type="mobile" vanity="CRUSH" quickdial="7" prio="1">01751234567</number>
                <number type="work" vanity="" prio="0">02239876543</number>
                <number type="fax_work" vanity="" prio="0">02239876599</number>
            </telephony>
        <contact>
            ...
        </contact>
        ...
    </phonebook>
</phonebooks>

Мои попытки со следующим кодом ...

foreach ($xml->phonebook->contact as $contact) {
    foreach ($contact->telephony->number as $number) {
        $attributes[(string)$number] = json_decode(json_encode((array) $number->attributes()), 1);
    }
}

дает мне полезный результат:

Array
(
    [01751234567] => Array
        (
            [@attributes] => Array
                (
                    [type] => mobile
                    [quickdial] => 7
                    [vanity] => CRUSH
                    [prio] => 1
                )
        )
     ...
)

... но я бы хотел это в более простой структуре. У кого-нибудь есть указания для меня, как легко устранить ненужный структурный уровень [@attributes]? Thx

1 Ответ

1 голос
/ 11 марта 2019

Вместо преобразования в JSON и обратно:

json_decode(json_encode((array) $number->attributes()), 1)

Зацикливание объектов и преобразование каждого в строку напрямую:

$attributesForThisNumber = [];
foreach ( $number->attributes() as $attrName => $attrObj ) {
    $attributesForThisNumber[] = (string)$attrObj;
}
$attributes[(string)$number] = $attributesForThisNumber;

Вы можете сделать это более компактным (но не обязательно более читабельным), используя:

  • iterator_to_array для получения простого массива объектов foreach будет дано (без маркера @attributes)
  • array_map над этим массивом вместо foreach
  • strval() для строки, брошенной вместо (string)

Предоставление:

$attributes[(string)$number] = array_map('strval', iterator_to_array($number->attributes()));
...