从 SimpeXML 转换时压缩数组

Compressing an array when converting from SimpeXML

我有以下 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]? 谢谢

而不是转换为 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()));