За последние 24 часа нас посетили 17542 программиста и 1724 робота. Сейчас ищут 903 программиста ...

XML в PHP

Тема в разделе "PHP для новичков", создана пользователем Klin, 17 май 2008.

  1. Klin

    Klin Активный пользователь

    С нами с:
    15 май 2008
    Сообщения:
    82
    Симпатии:
    0
    Есть такой код:


    PHP:
    1. <?php
    2.  
    3. $url = 'http://ws.darkagesworld.com/info.asmx/GetCastleInfo?rnd='.md5(uniqid(''));
    4.  
    5.  $ch = curl_init();
    6.  curl_setopt ($ch, CURLOPT_URL, "$url"); // Destination URL
    7.  curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // Output to a variable
    8.  
    9.  
    10.  $results = curl_exec($ch);
    11.  $XML = iconv('UTF-8','cp1251',$results);
    12.  
    13.  
    14.  
    15.  
    16.  
    17. $news = array();        // В этом массиве будут храниться новости,
    18.                         // полученные из XML файла
    19. $currentNews = null;    // Текущая новость. Используется в процессе
    20.                         // импорта данных
    21. $index = null;          // Текущий индекс в массиве новостей.
    22.                         // Используется в процессе импорта данных
    23.  
    24. // Функции, описанные ниже, являются обработчиками различных типов
    25. // XML-данных и будут вызываться парсером в процессе разбора.
    26.  
    27. // Функция для обработки начальных тегов XML
    28. // На входе:
    29. //   - указатель на SAX парсер
    30. //   - имя XML тега
    31. //   - массив аттрибутов
    32. function saxStartElement($parser,$name,$attrs)
    33. {
    34.     global $currentNews,$index;
    35.  
    36.     switch($name)
    37.     {
    38.         case 'CastleResult':
    39. // Тег newsLine содержит все новости. Мы должны подготовить
    40. // массив $news для приема новостей из XML файла.
    41.             $news = array();
    42.             break;
    43.         case 'CastleInfo':
    44. // Каждая новость находится в теге news. Подготавливаем массив
    45. // $currentNews для приема этой новости
    46.             $currentNews = array();
    47. // Если у новости есть дата - сохраняем ее в массиве
    48.             if (in_array('date',array_keys($attrs)))
    49.                 $currentNews['date'] = $attrs['date'];
    50.             break;
    51.         default:
    52. // Все остальные теги, которые могут встретиться в XML файле
    53. // находятся внутри тега <news>, поэтому мы просто запоминаем
    54. // их название с тем, чтобы знать, какие именно данные мы
    55. // обрабатываем.
    56.             $index = $name;
    57.             break;
    58.     };
    59. }
    60.  
    61. // Функция для обработки конечных тегов XML
    62. // На входе:
    63. //   - указатель на SAX парсер
    64. //   - имя XML тега
    65. function saxEndElement($parser,$name)
    66. {
    67.     global $news,$currentNews,$index;
    68.  
    69.     if ((is_array($currentNews)) && ($name=='CastleInfo'))
    70. // Если в данный момент у нас есть массив $currentNews (т.е.
    71. // мы обрабатываем содержимое новости) и имя закрывающего
    72. // тега - "news", то это значит, что данные для этой новости
    73. // кончились и мы можем поместить готовую новость в массив
    74. // новостей.
    75.     {
    76.         $news[] = $currentNews;
    77. // Уничтожаем массив текущей новости, чтобы показать, что
    78. // в данный момент мы не занимаемся получением данных для
    79. // новости.
    80.         $currentNews = null;
    81.     };
    82. // В любом случае закрытие тега означает, что символьные
    83. // данные, получаемые парсером не нужно помещать куда-либо.
    84.     $index = null;
    85. }
    86.  
    87. // Функция для обработки символьных данных
    88. // На входе:
    89. //   - указатель на SAX парсер
    90. //   - символьные данные XML
    91. function saxCharacterData($parser,$data)
    92. {
    93.     global $currentNews,$index;
    94.  
    95. // Мы принимаем только данные для новостей, помещенные в
    96. // какой-нибудь тег. Все остальные символьные данные
    97. // (как правило это пустое пространство, использованное
    98. // для форматирования) мы опускаем за ненадобностью.
    99.     if ((is_array($currentNews)) && ($index))
    100.         $currentNews[$index] = $data;
    101. }
    102.  
    103. // Создаем SAX парсер, который будет использоваться для
    104. // обработки XML-данных.
    105. $parser = xml_parser_create();
    106. // Регистрируем функции для обработки различных типов
    107. // XML-данных:
    108. //  - начальный и конечный тэги XML
    109. xml_set_element_handler($parser,'saxStartElement','saxEndElement');
    110. //  - символьные данные
    111. xml_set_character_data_handler($parser,'saxCharacterData');
    112. // Также существуют аналогичные функции для регистрации
    113. // обработчиков других типов XML-данных.
    114. // Убираем case folding, в этом случае имена тэгов будут
    115. // передаваться обработчикам в оригинальном виде. Если case
    116. // folding включен, то все имена тегов будут переведены
    117. // в верхний регистр.
    118. xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,false);
    119. // Получаем содержимое XML-файла с новостями.
    120. $xml = join('',file('castle.xml'));
    121.  
    122. // Производим парсинг (разбор) полученного XML-файла.
    123. // В процессе разбора парсер будет вызывать описанные нами
    124. // функции и в результате мы получим массив $news,
    125. // содержащий новости из XML-файла.
    126. if (!xml_parse($parser,$xml,true))
    127.  
    128. // Парсер возвращает значение FALSE, если произошла
    129. // какая-либо ошибка. В этом случае мы также прекращаем
    130. // выполнение скрипта и возвращаем ошибку.
    131.     die(sprintf('Ошибка XML: %s в строке %d',
    132.         xml_error_string(xml_get_error_code($parser)),
    133.         xml_get_current_line_number($parser)));
    134. // Уничтожаем парсер, освобождая занятые им ресурсы
    135. xml_parser_free($parser);
    136. print_r ($news);
    137. ?>

    Как мне в 120 строке вместо castle.xml подставить $XML чтобы все коректно отоброжалось???
     
  2. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    цитировать не буду, ровно как и рассказывать, но ссылочку на АФФТАРА, так усердно расставившего комментарии, обязан был поставить, ИМХО.
     
  3. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    а что, расскажите, будет очень любопытно :)
     
  4. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    код взят со странички http://www.providers.ru/articles/php/xm ... intro.html
    а как выполнить, то что нужно автару? - сначала надо узнать что он именно хотел.
    Точнее что именно у него хранится в $XML. Если массив с xml-тегами, - то file('castle.xml') меняем на $XML,
    а если просто xml-структура, то
    $xml = $XML;

    Думаю логично :) Или я ошибаюсь? ;)
     
  5. Klin

    Klin Активный пользователь

    С нами с:
    15 май 2008
    Сообщения:
    82
    Симпатии:
    0
    Извиняюсь что не так подрбно описал (я еще новичок вэтом деле). Содержание casle.xml

    <?xml version="1.0"?>
    <CastleResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ws.darkagesworld.com">
    <status>Ok</status>
    <serverTs>2008-05-17T14:57:09.8835118+04:00</serverTs>
    <castles>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Окрестности Альбинара</castleLocation>
    <castleName>Замок На Скале</castleName>
    <ownerClanName>Оправдатели Хаоса</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Альбинар</castleLocation>
    <castleName>Замок Девы</castleName>
    <ownerClanName>Brotherhood of Steel</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Окрестности Альбинара</castleLocation>
    <castleName>Замок Ангелов</castleName>
    <ownerClanName>Children Of Holy Shadow</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Окрестности Альбинара</castleLocation>
    <castleName>Замок Скорби</castleName>
    <ownerClanName>Клещи</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Окрестности Авалона</castleLocation>
    <castleName>Замок Стали</castleName>
    <ownerClanName>Клещи</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Окрестности Авалона</castleLocation>
    <castleName>Замок с Привидениями</castleName>
    <ownerClanName>VampireS</ownerClanName>
    <activeAssault>
    <startTs>2008-05-17T14:50:13.74+04:00</startTs>
    <attackers>
    <string>Serg M</string>
    </attackers>
    <defenders>
    <string>Maguchij Svin</string>
    </defenders>
    </activeAssault>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Окрестности Авалона</castleLocation>
    <castleName>Замок Белого Камня</castleName>
    <ownerClanName>Chambers DeaD</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Авалон</castleLocation>
    <castleName>Замок Страха</castleName>
    <ownerClanName>Империя</ownerClanName>
    <pendingAssaults>
    <BattleAppData>
    <startTs>2008-05-17T15:00:54.77125+04:00</startTs>
    <attackers>
    <string>Dark kitten</string>
    </attackers>
    </BattleAppData>
    </pendingAssaults>
    </CastleInfo>
    </castles>
    </CastleResult>

    Если я подставляю вместо 'castle.xml' $XML то выдает ошибку

    Warning: file($XML) [function.file]: failed to open stream: No such file or directory in Z:\home\localhost\www\moy\index.php on line 120

    Warning: join() [function.join]: Bad arguments. in Z:\home\localhost\www\moy\index.php on line 120
    Ошибка XML: Invalid document end в строке 1

    Содержание $XML

    <?xml version="1.0" encoding="utf-8"?>
    <CastleResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ws.darkagesworld.com">
    <status>Ok</status>
    <serverTs>2008-05-17T21:13:44.7042216+04:00</serverTs>
    <castles>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Окрестности Альбинара</castleLocation>
    <castleName>Замок На Скале</castleName>
    <ownerClanName>Оправдатели Хаоса</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Альбинар</castleLocation>
    <castleName>Замок Девы</castleName>
    <ownerClanName>Старперы</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Окрестности Альбинара</castleLocation>
    <castleName>Замок Ангелов</castleName>
    <ownerClanName>Children Of Holy Shadow</ownerClanName>
    <activeAssault>
    <startTs>2008-05-17T20:23:11.9397827+04:00</startTs>
    <attackers>
    <string>Useless</string>
    <string>globyska</string>
    <string>PODROSTOK</string>
    <string>Scavenger</string>
    </attackers>
    <defenders>
    <string>Warrior king</string>
    <string>Кира</string>
    <string>ХудойМачо</string>
    </defenders>
    </activeAssault>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Альбинара</countyName>
    <castleLocation>Окрестности Альбинара</castleLocation>
    <castleName>Замок Скорби</castleName>
    <ownerClanName>Клещи</ownerClanName>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Окрестности Авалона</castleLocation>
    <castleName>Замок Стали</castleName>
    <ownerClanName>Fallen Heroes</ownerClanName>
    <pendingAssaults>
    <BattleAppData>
    <startTs>2008-05-17T21:14:42.9275+04:00</startTs>
    <attackers>
    <string>Uranija</string>
    </attackers>
    </BattleAppData>
    </pendingAssaults>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Окрестности Авалона</castleLocation>
    <castleName>Замок с Привидениями</castleName>
    <ownerClanName>Fallen Heroes</ownerClanName>
    <pendingAssaults>
    <BattleAppData>
    <startTs>2008-05-17T21:14:48.380625+04:00</startTs>
    <attackers>
    <string>Черный</string>
    </attackers>
    </BattleAppData>
    </pendingAssaults>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Авалон</castleLocation>
    <castleName>Замок Страха</castleName>
    <ownerClanName>Fallen Heroes</ownerClanName>
    <activeAssault>
    <startTs>2008-05-17T21:05:17.380625+04:00</startTs>
    <attackers>
    <string>123GASHA</string>
    <string>АВПин</string>
    </attackers>
    <defenders>
    <string>CABRON</string>
    <string>lemmik</string>
    <string>STRELETS</string>
    <string>Злой мускул</string>
    <string>Мутант</string>
    <string>хаггинг</string>
    </defenders>
    </activeAssault>
    </CastleInfo>
    <CastleInfo>
    <countyName>Окрестности Авалона</countyName>
    <castleLocation>Окрестности Авалона</castleLocation>
    <castleName>Замок Белого Камня</castleName>
    <ownerClanName>Fallen Heroes</ownerClanName>
    <activeAssault>
    <startTs>2008-05-17T21:11:42.724375+04:00</startTs>
    <attackers>
    <string>istorik</string>
    </attackers>
    <defenders>
    <string>ViCer</string>
    </defenders>
    </activeAssault>
    </CastleInfo>
    </castles>
    </CastleResult>
     
  6. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    castle.xml - файл
    $XML - переменная со структурой xml. Разницу не видишь?
    Поясняю что делает строчка 120:
    $xml = join('',file('castle.xml'));

    1) file('castle.xml') - возвращает содержимое файла в виде массива строк
    2) join() - "склеивает", если можно так выразиться, элементы полученного массива в "строку" (опять же если можно так выразиться) с разделителем ''.
    Тебе, если у тебя в $XML лежит готовая структура (не массив, и не путь к хмл-файлу), нужно написать, вместо 120 строки просто:
    $xml = $XML;

    Правильно я объяснил, уважаемые гуру? :)
     
  7. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Хоть и не гуру, но отвечу: нет не правильно
    Автору вопроса не следует давать советы/ответы. Имхо
     
  8. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    topas
    хочу узнать Ваше мнение. С чем это связано? Он такой же как и все. Зашел и спросил...
    Объясните мне и я больше так не буду :):)
    тем более, что сам сейчас разбираюсь с этим хмл, а на топик на мой никто не отвечает :(
     
  9. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    ShamahN,
    Основное отличие автора от Вас: Вы стараетесь разобраться сами. Авотр же, в свою очередь, не желает сам вникать в суть проблемы: ему нужно, чтобы мы показали пальцем. И это для того, чтобы у Него работало. Имхо.
    Я, лично, такими вещами не занимаюсь, поэтому в этой теме меня больше не будет
     
  10. ShamahN

    ShamahN Активный пользователь

    С нами с:
    10 апр 2007
    Сообщения:
    1.449
    Симпатии:
    0
    Адрес:
    г.Волгодонск Роствской обл.
    topas
    Вашу точку зрения понял, но контингент для меня пока делится на тех кто помогает и кто ищет помощи. Может скоро начну разбираться ...