Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > simplexml_load_string и дефис


Автор: hetfield 31.7.2012, 13:07
Все доброго дня. Делаю небольшой сервис на основе api Яндекс услуг. 

Чтобы получить список услуг делаю вот такой запрос
Код

    $yakey = "ключ";
    
    $url_uslugi = 'http://api.uslugi.yandex.ru/1.0/banks/deposits/search?'
    .http_build_query(
        array(
        'key'=>$yakey,
        'region'=>'Киев',
    'currency'=>$currency,
        'period'=>$period,
        'sum'=>$sum,
    'payment-of-interest'=>$payment_of_interest,
    'capitalization'=>$capitalization,
    'replenishment'=>$replenishment,
    'limit'=>$limit
        )
    );
    
    $data  = YaGet2($url_uslugi);


$xmlObj = simplexml_load_string($data);



Если с запроса убрать "payment-of-interest", то все нормально, если оставить, то:
Код

simplexml_load_string() [function.simplexml-load-string]: Entity: line 1: parser error : Start tag expected, '<' not found in


Пытался делать так:
Код


$data = str_replace("payment-of-interest", "payment_of_interest", $data);
$xmlObj = simplexml_load_string($data);



не помогает... Очевидно, что вся проблема в дефисах. Как это побороть?


YaGet2:
Код

function YaGet2($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER , "http://" .$_SERVER['HTTP_HOST'] ); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array($url, 'GET'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $return = curl_exec($ch);

    if(curl_errno($ch)){
        $error = 'curl'.curl_errno($ch);
        return $error;
    }
    $http_code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        
    if ($http_code !== 200) {
        $error = 'http '.$http_code;
        return $error 
        . "<br>".$return ;
    } else {
         return $return;
    }
}


Автор: Fortop 31.7.2012, 13:33
Цитата(hetfield @  31.7.2012,  13:07 Найти цитируемый пост)
не помогает... Очевидно, что вся проблема в дефисах. Как это побороть?

очевидно вся проблема не в дефисах.

Где сам xml?
Вы его смотрели?

Что у вас пришло в  $data?

Автор: hetfield 31.7.2012, 13:44
В $data приходит такое (фрагмент):

Код

<deposits>
<deposit>
<id>195859</id>
<name>Наличные ежемесячно</name>
<link href="http://api.uslugi.yandex.ru/1.0/banks/deposits/195859" rel="self">
<link href="http://www.platinumbank.com.ua/view.dep6/" rel="www">
<bank>
<id>23312</id>
<name>Платинум Банк</name>
<company>ОАО «Платинум Банк»</company>
<rating>
<stars><value></value></stars></rating>
<link href="http://api.uslugi.yandex.ru/1.0/banks/23312" rel="self">
<link href="http://www.platinumbank.com.ua/" rel="www">
</bank>
<payment-of-interest>MONTHLY</payment-of-interest>
<capitalization>NO</capitalization>
<auto-prolongation>
<early-withdrawal>Досрочное снятие осуществляется по ставке «до востребования».</early-withdrawal>
<special-conditions>Автоматическая пролонгация до 3-х раз.
Бонусная акционная ставка при пролонгации:
- РІ гривнах РґРѕ +0,5;% 
- в долларах США до +0,1%;
- в евро до +0,05%.</special-conditions>
<short>
<rate>
<value>23.5</value>




Автор: Fortop 31.7.2012, 17:36
hetfield, А где тут xml?

первой строкой должно быть
Код

<?xml бла-бла-бла

Автор: Sanchezzz 31.7.2012, 18:20
YaGet2 ыы, знакомое название где то я его видел)  smile 
реплейсить нечего не нужно а работать вот в таком стиле если элемент stdClass:
Код

$data->{'advanced-repayment'}->scheme

Автор: BuShaRt 31.7.2012, 20:09
Вы уверены, что получаете именно XML и именно от Yandex? 

Цитата

Avoid "-" characters. If you name something "first-name," some software may think you want to subtract name from first.

Автор: hetfield 1.8.2012, 09:15
Цитата

А где тут xml? первой строкой должно быть


я фрагмент привел. Эта строка там есть


Код

$data->{'advanced-repayment'}->scheme


про это я знаю, но у меня ошибка вылетает на этапе, когда я делаю:

Код

$xmlObj = simplexml_load_string($data);


Обрабатывать сам xml после simplexml_load_string не проблема, если там есть дефс в именах. Вылетают ошибки в тот момент, когда я запрос отправляю с именами с дефисом
Код

$url_uslugi = 'http://api.uslugi.yandex.ru/1.0/banks/deposits/search?'
    .http_build_query(
        array(
        'key'=>$yakey,
        'region'=>'Киев',
        'currency'=>$currency,
        'period'=>$period,
        'sum'=>$sum,
        'payment-of-interest'=>$payment_of_interest,
        'capitalization'=>$capitalization,
        'replenishment'=>$replenishment,
        'limit'=>$limit
        )
    );




Цитата

Вы уверены, что получаете именно XML и именно от Yandex? 



ну да, собстна:
Код

$url_uslugi = 'http://api.uslugi.yandex.ru/1.0/banks/deposits/search?'


http://api.yandex.ru/uslugi/doc/banks-dg/concepts/deposits-search.xml

Автор: skyboy 1.8.2012, 20:40
Цитата(hetfield @  1.8.2012,  08:15 Найти цитируемый пост)
Вылетают ошибки в тот момент, когда я запрос отправляю с именами

ну, нет же! не в момент запроса, а в момент парсинга! следовательно, не должно быть разницы, к какому серверу запрос и с какими параметрами.
вот, если написать простой скрипт:
Код

$xml =<<<'XML'
твой XML-ответ здесь
XML;
simplexml_load_string($xml)

та же самая ошибка, нет?

Автор: Fortop 1.8.2012, 23:45
Цитата(hetfield @  1.8.2012,  09:15 Найти цитируемый пост)
я фрагмент привел. Эта строка там есть

Печаль, конспиратор вы наш.

У вас невалидный XML
Проверить причину его невалидности не представляется возможным, по одной простой причине....

Вы не умеете предоставлять необходимые данные для решения вопроса (собственно и вопрос-то таковой для вас, только по этой же причине).

У меня все работает даже с вашим битым кодом.

Код

<?php
$xml = '<?xml version="1.0" ?' . '>' .'
<deposits>
<deposit>
<id>195859</id>
<name>Наличные ежемесячно</name>
<link href="http://api.uslugi.yandex.ru/1.0/banks/deposits/195859" rel="self" />
<link href="http://www.platinumbank.com.ua/view.dep6/" rel="www" />
<bank>
<id>23312</id>
<name>Платинум Банк</name>
<company>ОАО «Платинум Банк»</company>
<rating>
<stars><value></value></stars></rating>
<link href="http://api.uslugi.yandex.ru/1.0/banks/23312" rel="self">
<link href="http://www.platinumbank.com.ua/" rel="www">
</bank>
<payment-of-interest>MONTHLY</payment-of-interest>
<capitalization>NO</capitalization>
<auto-prolongation>
<early-withdrawal>Досрочное снятие осуществляется по ставке «до востребования».</early-withdrawal>
<special-conditions>Автоматическая пролонгация до 3-х раз.
Бонусная акционная ставка при пролонгации:
- в гривнах до +0,5;% 
- в долларах США до +0,1%;
- в евро до +0,05%.</special-conditions>
<short>
<rate>
<value>23.5</value></rate>
';


$config = array(
           'indent'         => true,
           'output-xml'     => true,
           'wrap'           => 200);

$tidy = new tidy;
$tidy->parseString($xml, $config, 'utf8');
$tidy->cleanRepair();

$xml = simplexml_load_string($tidy);
var_dump($xml);

Автор: hetfield 2.8.2012, 11:40
ок, весь код

Код

function YaGet2($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER , "http://" .$_SERVER['HTTP_HOST'] ); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array($url, 'GET'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $return = curl_exec($ch);

    if(curl_errno($ch)){
        $error = 'curl'.curl_errno($ch);
        return $error;
    }
    $http_code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        
    if ($http_code !== 200) {
        $error = 'http '.$http_code;
        return $error 
        . "<br>".$return ;
    } else {
         return $return;
    }
}

function objectsIntoArray($arrObjData, $arrSkipIndices = array()) {
    $arrData = array();
   
    if (is_object($arrObjData)) {
        $arrObjData = get_object_vars($arrObjData);
    }
    if (is_array($arrObjData)) {
        foreach ($arrObjData as $index => $value) {
            if (is_object($value) || is_array($value)) {
                $value = objectsIntoArray($value, $arrSkipIndices); 
            }
            if (in_array($index, $arrSkipIndices)) {
                continue;
            }
            $arrData[$index] = $value;
        }
    }
    return $arrData;
}



    $yakey = "CFs72AACAAABMosZdKcV9FLQoz9G0Hy6zbByF1NOKyErZg";
    
    $url_uslugi = 'http://api.uslugi.yandex.ru/1.0/banks/deposits/search?'
    .http_build_query(
        array(
        'key'=>$yakey,
        'region'=>'Киев',
        'currency'=>$currency,
        'period'=>$period,
        'sum'=>$sum,
        'payment-of-interest'=>$payment_of_interest,
        'capitalization'=>$capitalization,
        'replenishment'=>$replenishment,
        'limit'=>$limit
        )
    );
    
    
    $data  = YaGet2($url_uslugi);


    $xmlObj = simplexml_load_string($data);
    $xmlArr = objectsIntoArray($xmlObj);



Цитата

У вас невалидный XML


От Яндекса? 



Вот что в $data
Код

<?xml version="1.0" encoding="UTF-8"?>
<deposits>
<deposit>
<id>99898</id>
<name>Хочу быть взрослым</name>
<link href="http://api.uslugi.yandex.ru/1.0/banks/deposits/99898" rel="self">
<link href="http://www.ukrgasbank.com/rus/personal/deposits/kinds/adult/" rel="www">
<bank>
<id>20942</id>
<name>Укргазбанк</name>
<company>ПАО АБ «Укргазбанк»</company>
<rating>
<stars><value></value></stars></rating>
<link href="http://api.uslugi.yandex.ru/1.0/banks/20942" rel="self">
<link href="http://www.ukrgasbank.com/rus/" rel="www">
</bank>
<restrictions>Депозит "Хочу быть взрослым" РѕС„ормляется исключительно РЅР° РёРјСЏ Рё РІ интересах малолетних Рё несовершеннолетних лиц. Вкладчиком РїРѕ депозиту "Хочу быть взрослым" РјРѕРіСѓС‚ быть малолетние лица СЃ даты рождения РґРѕ 17-летнего возраста. Дата окончания действия РґРѕРіРѕРІРѕСЂР° РЅРµ может превышать дату достижения вкладчиком 18-ти летнего возраста +10 календарных дней.</restrictions>
<payment-of-interest>QUARTERLY</payment-of-interest>
<capitalization>YES</capitalization>
<partial-withdrawal>
<restrictions>Дважды в год. При условии, что вкладчику на дату досрочного снятия части депозита исполнилось 16 лет.</restrictions>
</partial-withdrawal>
<replenishment>
<restrictions>Не позднее чем за 365 дней до окончания срока действия договора. Минимальная сумма пополнения - 100,00 гривен, 20,00 долларов США, 20,00 евро.</restrictions>
</replenishment>
<early-withdrawal>РџСЂРё досрочном расторжении РґРѕРіРѕРІРѕСЂР° РІ течение первых 32 календарных дней СЃ даты начала СЃСЂРѕРєР° размещения депозита проценты Р·Р° весь СЃСЂРѕРє размещения средств РЅР° депозитном счете переcчитываются РїРѕ сниженной ставке, РёР· расчета 0,001% годовых.  РџСЂРё досрочном расторжении РґРѕРіРѕРІРѕСЂР° РІ период после 32 календарных дней СЃ даты начала СЃСЂРѕРєР° размещения депозита проценты Р·Р° весь СЃСЂРѕРє размещения средств РЅР° депозитном счете переcчитываются РїРѕ сниженной ставке, РёСЃС…РѕРґСЏ РёР· расчета 1% годовых.</early-withdrawal>
<special-conditions>Дата окончания действия РґРѕРіРѕРІРѕСЂР° РЅРµ может превышать дату достижения вкладчиком 18-ти летнего возраста +10 календарных дней. Р’СЃРµ вкладчики, которые оформили депозит больше чем РЅР° 60 месяцев (5 лет), после достижения 18-ти летнего возраста имеют право получить кредит РїРѕ любой кредитной программе РђР‘ "Укргазбанк" РґР»СЏ физических лиц РІ СЃСѓРјРјРµ, которая РЅРµ превышает 5 кратного размера депозита РЅР° момент достижения 18-ти летнего возраста. РџСЂРё этом, процентная ставка РїРѕ кредиту уменьшается РЅР° 1% годовых РѕС‚ базовых процентных ставок РїРѕ кредитам.
Ставка увеличивается РЅР° 1 Рї.Рї. годовых РїСЂРё размещении депозита РЅР° СЃСѓРјРјСѓ РѕС‚ 500 000,00 гривен РЅР° СЃСЂРѕРє РѕС‚ 3 месяцев (РѕС‚ 93 дней).
Ставка увеличивается РЅР° 0,2 Рї.Рї. годовых РїРѕ вкладам РІ национальной валюте, РґРѕР». РЎРЁРђ Рё евро для собственников карточных счетов, открытых РІ РђР‘ "Укргазбанк" РґР»СЏ получения пенсий Рё помощи Р·Р° счёт средств Пенсионного фонда Украины.</special-conditions>
<short>
<rate>
<value>12.0</value>
</rate>
<period interval="DAY">365</period>
<income>3138.4</income>
</short>
</deposit>
</deposits>


Добавлено через 9 минут и 45 секунд
Мда, похоже я тупил... 

Ошибки были, когда payment-of-interest, на который я грешил был пустой.  Если там есть значение, то все нормально. У самого Яндекса написано, что пустыми значения могут быть... В общем, пока вопрос исчерпан, кто помогал  smile 

Автор: Fortop 2.8.2012, 12:34
Цитата(hetfield @  2.8.2012,  11:40 Найти цитируемый пост)
От Яндекса? 

А там не люди работают?

Или вам его отдали неправильно.
Или вы его получили неправильно.

факт остается фактом.

Показываю. Возьмете source.xml и target.xml и сравните.


Код

<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<deposits>
<deposit>
<id>99898</id>
<name>Хочу быть взрослым</name>
<link href="http://api.uslugi.yandex.ru/1.0/banks/deposits/99898" rel="self" >
<link href="http://www.ukrgasbank.com/rus/personal/deposits/kinds/adult/" rel="www" >
<bank>
<id>20942</id>
<name>Укргазбанк</name>
<company>ПАО АБ «Укргазбанк»</company>
<rating>
<stars><value></value></stars></rating>
<link href="http://api.uslugi.yandex.ru/1.0/banks/20942" rel="self" >
<link href="http://www.ukrgasbank.com/rus/" rel="www" >
</bank>
<restrictions>Депозит "Хочу быть взрослым" оформляется исключительно на имя и в интересах малолетних и несовершеннолетних лиц. Вкладчиком по депозиту "Хочу быть взрослым" могут быть малолетние лица с даты рождения до 17-летнего возраста. Дата окончания действия договора не может превышать дату достижения вкладчиком 18-ти летнего возраста +10 календарных дней.</restrictions>
<payment-of-interest>QUARTERLY</payment-of-interest>
<capitalization>YES</capitalization>
<partial-withdrawal>
<restrictions>Дважды в год. При условии, что вкладчику на дату досрочного снятия части депозита исполнилось 16 лет.</restrictions>
</partial-withdrawal>
<replenishment>
<restrictions>Не позднее чем за 365 дней до окончания срока действия договора. Минимальная сумма пополнения - 100,00 гривен, 20,00 долларов США, 20,00 евро.</restrictions>
</replenishment>
<early-withdrawal>При досрочном расторжении договора в течение первых 32 календарных дней с даты начала срока размещения депозита проценты за весь срок размещения средств на депозитном счете переcчитываются по сниженной ставке, из расчета 0,001% годовых.  При досрочном расторжении договора в период после 32 календарных дней с даты начала срока размещения депозита проценты за весь срок размещения средств на депозитном счете переcчитываются по сниженной ставке, исходя из расчета 1% годовых.</early-withdrawal>
<special-conditions>Дата окончания действия договора не может превышать дату достижения вкладчиком 18-ти летнего возраста +10 календарных дней. Все вкладчики, которые оформили депозит больше чем на 60 месяцев (5 лет), после достижения 18-ти летнего возраста имеют право получить кредит по любой кредитной программе АБ "Укргазбанк" для физических лиц в сумме, которая не превышает 5 кратного размера депозита на момент достижения 18-ти летнего возраста. При этом, процентная ставка по кредиту уменьшается на 1% годовых от базовых процентных ставок по кредитам.
Ставка увеличивается на 1 п.п. годовых при размещении депозита на сумму от 500 000,00 гривен на срок от 3 месяцев (от 93 дней).
Ставка увеличивается на 0,2 п.п. годовых по вкладам в национальной валюте, дол. США и евро для собственников карточных счетов, открытых в АБ "Укргазбанк" для получения пенсий и помощи за счёт средств Пенсионного фонда Украины.</special-conditions>
<short>
<rate>
<value>12.0</value>
</rate>
<period interval="DAY">365</period>
<income>3138.4</income>
</short>
</deposit>
</deposits>
';
file_put_contents('source.xml', $xml);

$dom = new DomDocument();
$dom->recover = true;
$dom->loadXML($xml);
$dom->save('result.xml);



Добавлено через 1 минуту и 22 секунды
hetfield, и ключ API потрите.
Нужны были только данные которые вы получили.

Добавлено через 3 минуты и 15 секунд
Ну и пользуйтесь вот таким хотя бы

http://www.w3schools.com/xml/xml_validator.asp

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)