В Yandex Direct API имеется инструмент подключения к данным сервиса, чтобы генерировать аналитическую отчетность по маркетинговым кампаниям. Чтобы получить данные, необходимо отправлять на сервер API запросы и сервер возвращает результат в формате JSON. Пока что QlikView не умеет напрямую работать с этим форматом, поэтому одним из выходов является написание конвертора формата JSON в формат XML. Yandex Metrika умеет возвращать формат XML, Yandex Direct пока что отдает данные в JSON.
Ниже приведен пример php-скрипта, который преобразует JSON в XML. Плюс вызывается функция для преобразования результата Yandex Direct API в XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
<?php /** * Эта вспомогательная функция проверяет, является ли массив * ассоциативным - то есть есть ли в нем строковые ключи * * @param array $array * @return bool */ function isAssocArray($array) { if(!is_array($array)) { return false; } if(count($array) < 1) { return true; } foreach($array as $key => $value) { if(is_numeric($key)) { return false; } } return true; } /** * Эта вспомогательная функция генерирует XML-элемент * * @param mixed $content Содержимое элемента * @param string $parent_tag Имя родительского тега на случай, если * * @return bool */ function generateXmlTagContents($content, $parent_tag = 'WHATTAG') { if(is_array($content)) { // Содержимое - массив if(isAssocArray($content)) { // Содержимое - массив вида array('id' => ..., 'name' => ...) return arrayToXml($content); } else { // Содержимое - массив вида array(0 => ..., 1 => ...) $result = ''; foreach($content as $content_value) { $result .= "<{$parent_tag}>" . generateXmlTagContents($content_value, $parent_tag) . "</{$parent_tag}>"; } return $result; } } else { // Содержимое - не массив. $content = (string)$content; if(preg_match('#[<>&]#', $content)) { // Если в содержимом есть специальные символы, то его нужно обернуть в <![CDATA[...]]> return "<![CDATA[{$content}]]>"; } return $content; } } /** * Эта функция генерирует XML на основе массива * * @param array $array Исходный массив * @return string Итоговый XML */ function arrayToXml(array $array) { $result = ''; foreach($array as $tag => $content) { // Сделать $tag (будущее имя тега) маленькими буквами $tag = strtolower($tag); // Эта строка вырезает из имени тега все буквы, кроме // латинского алфавита, дефиса, подчеркивания, двоеточия // и цифр (эти символы разрешены в именах тегов XML) // (ну, не только они, на самом деле, но в основном используются они) $tag = preg_replace('#[^-_:a-z0-9]#', '', $tag); if(is_array($content) && isAssocArray($content) === false) { // Если содержимое - это массив с числовыми ключами, то выводить сам тэг // сейчас не нужно - у каждого элемента он будет свой, сгенерированный // функцией generateXmlTagContents() $result .= generateXmlTagContents($content, $tag); } else { // В противном случае это обычный элемент, и мы выводим сам тэг, а // generateXmlTagContents() займется его содержимым. $result .= "<{$tag}>" . generateXmlTagContents($content, $tag) . "</{$tag}>"; } } return $result; } // ---- Ниже пример использования функции arrayToXml() -------------------- $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,'https://api-sandbox.direct.yandex.com/json/v5/keywords'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS,'{"method":"get","params":{"SelectionCriteria":{"CampaignIds":[181497,181498,181499]},"FieldNames":["Id","Keyword","State","Status","AdGroupId","CampaignId","Bid","ContextBid","StrategyPriority"] }}'); //Post Fields curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $headers = [ 'POST /json/v5/keywords/ HTTP/1.1', 'Host: api-sandbox.direct.yandex.com', 'Authorization: Bearer AQAAAAAJ8KAaAAP5x0wl5UonY0Cfu3KFIyi1aUY', 'Accept-Language: ru', 'Client-Login: iv-shamaev', 'Content-Type: application/json; charset=utf-8', ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $server_output = curl_exec ($ch); curl_close ($ch); $data = json_decode($server_output, true); $result = arrayToXml($data); // Указать, что весь последующий вывод - это XML // Но надо иметь в виду, что до этой команды ничего нельзя выводить. header('Content-Type: text/xml; charset=utf-8'); // Эта строка нужна в начале каждого XML-файла echo '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>'; // После нее можно вывести само содержимое echo $result; ?> |
Преобразование JSON в XML требуется для интеграции Yandex Direct API с QlikView. Код вставляется в script_name.php на домене и данные загружаются через URL:
1 |
http://my_domain_name.ru/script_name.php |
Еще один пример с обычным массивом JSON, который преобразуется в XML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
<?php /** * Эта вспомогательная функция проверяет, является ли массив * ассоциативным - то есть есть ли в нем строковые ключи * * @param array $array * @return bool */ function isAssocArray($array) { if(!is_array($array)) { return false; } if(count($array) < 1) { return true; } foreach($array as $key => $value) { if(is_numeric($key)) { return false; } } return true; } /** * Эта вспомогательная функция генерирует XML-элемент * * @param mixed $content Содержимое элемента * @param string $parent_tag Имя родительского тега на случай, если * * @return bool */ function generateXmlTagContents($content, $parent_tag = 'WHATTAG') { if(is_array($content)) { // Содержимое - массив if(isAssocArray($content)) { // Содержимое - массив вида array('id' => ..., 'name' => ...) return arrayToXml($content); } else { // Содержимое - массив вида array(0 => ..., 1 => ...) $result = ''; foreach($content as $content_value) { $result .= "<{$parent_tag}>" . generateXmlTagContents($content_value, $parent_tag) . "</{$parent_tag}>"; } return $result; } } else { // Содержимое - не массив. $content = (string)$content; if(preg_match('#[<>&]#', $content)) { // Если в содержимом есть специальные символы, то его нужно обернуть в <![CDATA[...]]> return "<![CDATA[{$content}]]>"; } return $content; } } /** * Эта функция генерирует XML на основе массива * * @param array $array Исходный массив * @return string Итоговый XML */ function arrayToXml(array $array) { $result = ''; foreach($array as $tag => $content) { // Сделать $tag (будущее имя тега) маленькими буквами $tag = strtolower($tag); // Эта строка вырезает из имени тега все буквы, кроме // латинского алфавита, дефиса, подчеркивания, двоеточия // и цифр (эти символы разрешены в именах тегов XML) // (ну, не только они, на самом деле, но в основном используются они) $tag = preg_replace('#[^-_:a-z0-9]#', '', $tag); if(is_array($content) && isAssocArray($content) === false) { // Если содержимое - это массив с числовыми ключами, то выводить сам тэг // сейчас не нужно - у каждого элемента он будет свой, сгенерированный // функцией generateXmlTagContents() $result .= generateXmlTagContents($content, $tag); } else { // В противном случае это обычный элемент, и мы выводим сам тэг, а // generateXmlTagContents() займется его содержимым. $result .= "<{$tag}>" . generateXmlTagContents($content, $tag) . "</{$tag}>"; } } return $result; } // ---- Ниже пример использования функции arrayToXml() -------------------- $input = ' { "Result":{ "Product":[ {"Id":181497,"Name":"Product 1"}, {"Id":181498,"Name":"Product 2"}, {"Id":181499,"Name":"Product 3"}, {"Id":181499,"Name":"Pr<od&uct 3"} ] } }'; $data = json_decode($input, true); $result = arrayToXml($data); // Указать, что весь последующий вывод - это XML // Но надо иметь в виду, что до этой команды ничего нельзя выводить. header('Content-Type: text/xml; charset=utf-8'); // Эта строка нужна в начале каждого XML-файла echo '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>'; // После нее можно вывести само содержимое echo $result; ?> |
Получили код для загрузки данных в QlikView из JSON через преобразование в XML:
1 2 3 4 5 6 |
// Start of [arraytoxml.php] LOAD statements product: LOAD id, name FROM [http://my_domain_name.ru/arraytoxml.php] (XmlSimple, Table is [result/product]); // End of [arraytoxml.php] LOAD statements |
Leave a Reply