PHP конвертирует XML в группу JSON, когда есть один ребенок

Я использую этот класс PHP для преобразования XML в JSON: http://www.ibm.com/developerworks/library/x-xml2jsonphp/

Например, для этого XML:

<?xml version="1.0" encoding="UTF-8"?> <searchResult> <status>OK</status> <users> <user> <userName>johndoe</userName> </user> <user> <userName>johndoe1</userName> <fullName>John Doe</fullName> </user> <user> <userName>johndoe2</userName> </user> <user> <userName>johndoe3</userName> <fullName>John Doe Mother</fullName> </user> <user> <userName>johndoe4</userName> </user> </users> </searchResult> 

Результат:

 { "searchResult": { "status": "OK", "users": { "user": [ { "userName": "johndoe" }, { "userName": "johndoe1", "fullName": "John Doe" }, { "userName": "johndoe2" }, { "userName": "johndoe3", "fullName": "John Doe Mother" }, { "userName": "johndoe4" } ] } } } 

Но я бы хотел:

 { "searchResult": { "status": "OK", "users": [ { "userName": "johndoe" }, { "userName": "johndoe1", "fullName": "John Doe" }, { "userName": "johndoe2" }, { "userName": "johndoe3", "fullName": "John Doe Mother" }, { "userName": "johndoe4" } ] } } 

Группировка «user» в «users», потому что это массив с одним ребенком.

Я ищу другой класс для преобразования XML в JSON, чтобы получить этот результат, но я не нашел никаких ресурсов.

Не могли бы вы помочь мне решить мою проблему.

Спасибо заранее, с наилучшими пожеланиями Фабрицио

Статья, с которой вы связаны, довольно устарела. Например, Services_JSON обычно не требуется.

Стабильная версия PHP 5.4 теперь имеет функцию json_encode() и интерфейс JsonSerializable а также iterator_to_array . Даже если вы используете более старую версию PHP 5.3, следующий пример довольно легко принять.

Так что вам действительно нужна ваша собственная JSON-кодировка SimpleXMLElement .

Итак, прежде всего, давайте просто создадим «наш собственный» Json encoder:

 class XML2Json extends SimpleXMLElement { } 

Вау. Это было просто. Давайте проверим, что он работает:

 $converter = new XML2Json($bufferXml); echo json_encode($converter, JSON_PRETTY_PRINT), "\n"; 

И результат уже аналогичен результату с Services_JSON :

 { "status": "OK", "users": { "user": [ { "userName": "johndoe" }, { "userName": "johndoe1", "fullName": "John Doe" }, { "userName": "johndoe2" }, { "userName": "johndoe3", "fullName": "John Doe Mother" }, { "userName": "johndoe4" } ] } } 

Но это не подходит. Как показывает результат, свойство searchResult отсутствует, а также пользователи не находятся в одном массиве, как вы этого хотите.

Поэтому json_encode должен быть определен пользователем. Для этого в PHP PHP имеет интерфейс JsonSerializable . Он состоит из одного метода с именем jsonSerialize() и теперь мы вернем ему другое значение, если имя searchResult предложило как имя, так и имя пользователя как плоский массив. Давайте расширим и реализуем интерфейс:

 class XML2JsonSearchResult extends XML2Json implements JsonSerializable { public function jsonSerialize() { $name = $this->getName(); if ($name !== 'searchResult') { return $this; } $value = (array)$this; $value['users'] = iterator_to_array($value['users']->user, FALSE); return [$name => $value]; } } 

Все элементы, не имеющие имени searchResult , получат стандартную кодировку JSON, возвращая $this .

Идентификатор searchResult будет назван, и его пользователи будут сплющены функцией iterator_to_array() .

И это все, что вам нужно. Опять пример использования, он работает точно так же, только на этот раз имя класса отличается:

 $converter = new XML2JsonSearchResult($bufferXml); echo json_encode($converter, JSON_PRETTY_PRINT); 

И теперь результат выглядит так, как вы этого хотите:

 { "searchResult": { "status": "OK", "users": [ { "userName": "johndoe" }, { "userName": "johndoe1", "fullName": "John Doe" }, { "userName": "johndoe2" }, { "userName": "johndoe3", "fullName": "John Doe Mother" }, { "userName": "johndoe4" } ] } } 

Надеюсь, это даст вам хороший пример, как это сделать в наши дни.

Полный пример кода с первого взгляда ( онлайн-демонстрация ):

 class XML2JsonSearchResult extends SimpleXMLElement implements JsonSerializable { public function jsonSerialize() { $name = $this->getName(); if ($name !== 'searchResult') { return $this; } $value = (array)$this; $value['users'] = iterator_to_array($value['users']->user, FALSE); return [$name => $value]; } } $converter = new XML2JsonSearchResult($bufferXml); echo json_encode($converter, JSON_PRETTY_PRINT);