помогите с парсингом XML

musicant

Новичок
помогите с парсингом XML

Добрый день!
Я в XML новичек, и застрял почти на ровном месте.

Вот часть кода xml:
<packets>
<packet>
<packetHeader>
<tour key="" name="" nameLat="" countryKey="" cityFromKey="" />
<spo key="" name="" nameLat="" for="" validFrom="" validTo="" issue="" issueTime="" spoState="" priceCount="">
<dates>
<date>yyy-mm-dd</date>
<date>yyy-mm-dd</date>
<date>yyy-mm-dd</date>
<date>yyy-mm-dd</date>
<date>yyy-mm-dd</date>
</dates>
</spo>
</packetHeader>
....
</packet>

</packets>

Блок <packet></packet> повторяется много раз. количество элементов <date></date> каждый раз меняется.

Делаю так:
$data=$client->__getLastResponse();
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($p, $data, $vals, $index);
xml_parser_free($p);
$tours=array();
$spo=array();
...

foreach($vals as $el)
{
if($el['tag']=="tour"){
if(isset($el['attributes'])&&isset($el['attributes']['name']))
$tours[]=$el['attributes']['name'];
...
}
if($el['tag']=="spo"){
if(isset($el['attributes'])&&isset($el['attributes']['key']))
$spo[]=$el['attributes']['key'];
...
}
}
Не могу понять, как вытащить даты из <dates></dates>
Вытащить вобще все даты - не проблема, а даты только из текущего <dates></dates>.....
Потом все это идет в MySQL.

Подскажите пожалуйста правильное решение.
 

c0dex

web.dev 2002-...
Команда форума
Партнер клуба
PHP:
$str = '
<packets>
    <packet>
        <packetHeader>
            <tour key="" name="" nameLat="" countryKey="" cityFromKey="" />
            <spo key="" name="" nameLat="" for="" validFrom="" validTo="" issue="" issueTime="" spoState="" priceCount="">
                <dates>
                    <date>yyy-mm-dd</date>
                    <date>yyy-mm-dd</date>
                    <date>yyy-mm-dd</date>
                    <date>yyy-mm-dd</date>
                    <date>yyy-mm-dd</date>
                </dates>
            </spo>
        </packetHeader>
    </packet>
</packets>';

$xml = simplexml_load_string($str);
echo "<pre>";
print_r($xml);
дальше сам.
 

musicant

Новичок
c0dex
Забыл сказать, что xml получаю от SOAP клиента и simplexml отказывается ее обрабатывать.
Поэтому я и воспользовался xml_parse_into_struct



-~{}~ 21.01.10 15:56:

О!
нашел решение в интернете:
$xmlstr = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $data);

Теперь simplexml работает, дальше наверно сам разберусь :)
 

Sigorma

Новичок
это решение кажется более красивым
http://e-mats.org/2009/08/parsing-xml-with-namespaces-with-simplexml/

если я правильно понял в чем у тебя проблема то поможет
PHP:
$data = $xml->xpath('//Body');
print_r($data);
 

musicant

Новичок
Sigorma
Так действительно намного проще!
Спасибо!

-~{}~ 22.01.10 21:20:

Елки...
Только разобрался, а владельцы Вэб сервиса перевели ответ в формат TourML :)
Вроде ничего не изменилось кроме...тех самых namespaces....
<?xml version="1.0" encoding="utf-8"?>
<TourML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" date="2010-01-22" time="19:23:57.5121181+03:00" xmlns="urn:tourml:products/2004-04-19">
<header name="..." uri="http://www.....ru" />

И снова в поисках.
 

Sigorma

Новичок
musicant
есть линк на пример?
сам работаю в области тур операторов но о TourML слышу первый раз, интересно посмотреть что за зверь такой.
 

Sigorma

Новичок
PHP:
<?php 
# SoapClient, cUrl 
$file = file_get_contents('sample/tourml.xml'); 

$xml = new SimpleXMLElement($file); 

$elements = $xml->xpath('//*'); 

# element "header"
var_dump($elements[0]->header); 
?>
-~{}~ 23.01.10 00:11:

полезно будет для начала почитать http://i-novice.net/phpxmlxpath-chast-1/
 

musicant

Новичок
Спасибо!
Обязательно почитаю!

-~{}~ 24.01.10 01:52:

вопрос - как логичнее сделать?

Я записываю всю инфу из XML в базу MySQL, чтоб потом использовать ее для поиска туров.
Просто прохожу циклом и записываю в базу по строке при каждом проходе.
В каждом туре есть список дат - количество дат заранее не известно(каждый проход цикла возвращает их массивом без разделителей)

Как лучше записать даты в базу, учитывая, что(в т.ч.) по ним потом будет вестись поиск?
Перевести массив в строку и записать строкой? или есть еще какой нибудь вариант?
Может создать для дат отдельную таблицу и прописывать к каждой дате номер тура?
 

fixxxer

К.О.
Партнер клуба
>создать для дат отдельную таблицу и прописывать к каждой дате номер тура

да

и хранить в подобающем типе поля - индекс будет эффективнее
 

AmdY

Пью пиво
Команда форума
только, наверное, не к каждой дате, а промежутки
tour_id start_at end_at
 

fixxxer

К.О.
Партнер клуба
я конечно не специалист, но по моему длительность туров обычно фиксированная, и лучше таки хранить именно длительность один раз. хотя может и не прав.

-~{}~ 24.01.10 03:33:

а еще ведь могут быть туры из разряда "каждую пятницу". не все так просто тут...
 
Сверху