LINUX.ORG.RU

xml2array. Вопрос идеологический, блин...


0

0

Рассмотрим абстрактный автономный парсер XML в массив.

Что хочется:

<root>
 <title>title1</title>
 <title>title2</title>
</root>

Получить в виде:

{ 'root' =>
 {
  'title' => ['title1', 'title2' ]
 }
}

<root>
<time>1234567</time>
</root>

в виде

{ 'root' => { 'time' => 1234567 } }

Понятно, чтобы по parsed_data['root']['time'] или по parsed_data['root']['titles'][0] удобно доставать данные.

И вот тут облом. При парсинге заранее неизвестно, массив элементов будет или одиночный элемент. Т.е. если грантированно более одного элемента, то всё понятно: если уже есть одиночный распарсеный элемент - преобразуем его в массив и новые добавляем в массив.

Но тогда, если в массиве значений только одна запись, получим ошибку:

<root>
 <title>title1</title>
</root>

получим

{ 'root' => 
 {
  'title' => 'title1'
 }
}

вместо

{ 'root' => 
 {
  'title' => ['title1']
 }
}

Например, RSS с одной записью:

<channel>
 <item><link>...</link></item>
</channel>

будет давать совсем другой результат, чем с несколькими:

<channel>
 <item><link>...</link></item>
 <item><link>...</link></item>
 <item><link>...</link></item>
</channel>

«Правильное» решение приходит в голову такое. Все элементы парсить как массивы изначально. Т.е. в случае одиночных записей будем просто иметь массив из одного элемента:

<root>
<time>1234567</time>
</root>
в
{ 'root' => [{ 'time' => [1234567] } ]}

Но некрасиво каждый раз писать, типа data['root'][0]['time'][0]

Нет ли какого-то более изящного решения? :-/

★★★★★

Вроде бы были пакеты с поддержкой XPath/XQuery/XQL. Хотя там возможно поддерживается только выборка, но изменения так же возможно делать через выборку. А вообще саме идеологически правильное решение, смотреть как сделано в SXML и перенести это дело на Perl.

SV0L0CH ()

В php можно операции перегружать? Т.е. сделать некий класс, который с одной стороны можно использовать как массив, с другой как строку.

А вообще хороший интерфейс к XPath по удобству не уступает предложенному варианту. Производительность, конечно, хуже.

Legioner ★★★★★ ()
Ответ на: комментарий от Legioner

>В php можно операции перегружать?

Нельзя, но это легко обходится, если нужно.

Т.е. сделать некий класс, который с одной стороны можно использовать как массив, с другой как строку.


Т.е. когда data['title'] == data['title'][0]? Да, так нельзя. Но мысль здравая. Никто не запрещает тупо продублировать значение 'title'. И с индексом и без (в PHP все массивы - ассоциативные).

Да, это будет вменяемым решением...

А вообще хороший интерфейс к XPath по удобству не уступает предложенному варианту


Хм. Погуглил - интересно. PHP умеет xpath «изкоробочно». Правда, чистый xpath - только в PHP4, в PHP5 - DOMXPath. Пощупаю.

KRoN73 ★★★★★ ()

Я бы предложил вам лисп.

bk_ ★★ ()

парсить xml с помощью jaxb в джава обьекты, сериализовать в json любым сериализатором, например jackson. Все.

JFreeM ★★★☆ ()
Ответ на: комментарий от KRoN73

ах, пых. ССЗБ. Тогда только ручками. К сожалению, для такого молодого ЯП еще не успели написать достаточно библиотек.

JFreeM ★★★☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.