У меня есть xml, это простая версия.
<xml> <items> <item abc="123">item one</item> <item abc="456">item two</item> </items> </xml>
Используя SimpleXML в контенте,
$obj = simplexml_load_string( $xml );
Я могу использовать $obj->xpath( '//items/item' );
и получить доступ к @attributes.
Мне нужен результат массива, поэтому я попробовал json_decode(json_encode($obj),true)
трюк, но это похоже на удаление доступа к @attributes (т.е. abc = "123").
Есть ли другой способ сделать это, который обеспечивает доступ к атрибутам и оставляет меня с массивом?
Вы можете пройти маршрут с помощью json_encode
и json_decode
и вы можете добавить материал, который вам не хватает, потому что json_encode
-ing следует определенным правилам с SimpleXMLElement
.
Если вас интересуют правила и их детали, я написал два блога:
Для вас, возможно, более интересной является третья часть, которая показывает, как вы можете изменить сериализацию json и предоставить свой собственный формат (например, для сохранения атрибутов):
Он поставляется с полным примером, вот выдержка из кода:
$xml = '<xml> <items> <item abc="123">item one</item> <item abc="456">item two</item> </items> </xml>'; $obj = simplexml_load_string($xml, 'JsonXMLElement'); echo $json = json_encode($obj, JSON_PRETTY_PRINT), "\n"; print_r(json_decode($json, TRUE));
Вывод JSON и массива следующий: обратите внимание, что атрибуты являются его частью:
{ "items": { "item": [ { "@attributes": { "abc": "123" }, "@text": "item one" }, { "@attributes": { "abc": "456" }, "@text": "item two" } ] } } Array ( [items] => Array ( [item] => Array ( [0] => Array ( [@attributes] => Array ( [abc] => 123 ) [@text] => item one ) [1] => Array ( [@attributes] => Array ( [abc] => 456 ) [@text] => item two ) ) ) )
Вам нужно вызвать функцию attributes ().
Образец кода:
$xmlString = '<xml> <items> <item abc="123">item one</item> <item abc="456">item two</item> </items> </xml>'; $xml = new SimpleXMLElement($xmlString); foreach( $xml->items->item as $value){ $my_array[] = strval($value->attributes()); } print_r($my_array);
Eval
$xml = new SimpleXMLElement($xmlString);
$ xml теперь является объектом. Чтобы получить значение атрибута:
$xml->something['id'];
Где 'id' – это имя атрибута.
Хотя теоретически возможно написать общее преобразование из XML в структуры PHP или JSON, очень сложно зафиксировать все тонкости, которые могут присутствовать, – различие между дочерними элементами и атрибутами, текстовое содержимое наряду с атрибутами (как вы здесь) или даже рядом с дочерними элементами, несколькими дочерними узлами с одинаковым именем, важно ли порядок дочерних элементов и текстовых узлов (например, в XHTML или DocBook) и т. д. и т. д.
Если у вас есть определенный формат, который вам нужно создать, проще будет использовать API-интерфейс, такой как SimpleXML, для обработки XML-кода и создания необходимой структуры.
Вы не указываете структуру, которую хотите достичь, но общий подход, учитывая ваш вход, состоял бы в том, чтобы перебирать каждый элемент и либо получать доступ к известным атрибутам, либо обходить каждый атрибут:
$sxml = simplexml_load_string( $xml ); $final_array = array(); foreach ( $sxml->items->item as $xml_item ) { $formatted_item = array(); // Text content of item $formatted_item['content'] = (string)$xml_item; // Specifically get 'abc' attribute $formatted_item['abc'] = (string)$xml_item['abc']; // Maybe one of the attributes is an integer $formatted_item['foo_id'] = (int)$xml_item['foo_id']; // Or maybe you want to loop over lots of possible attributes foreach ( $xml_item->attributes() as $attr_name => $attr_value ) { $formatted_item['attrib:' . $attr_name] = (string)$attr_value; } // Add it to a final list $final_array[] = $formatted_item; // Or maybe you want that array to be keyed on one of the attributes $final_array[ (string)$xml_item['key'] ] = $formatted_item; }
Вот класс, который я нашел, который способен обрабатывать XML в массиве очень красиво: http://outlandish.com/blog/xml-to-json/ ( backup ). Преобразование в json – это вопрос вызова json_encode()
.