AlexeyV
Новичок
Как корректно прочитать сложный xml
Добрый день!
Помогите, что то я совсем запутался.
Есть xml в котором несколько полей <Text>...</Text>
Нужно его корректно прочитать парсеров для PHP, так чтобы и под FreeBSD и под Win работало.
Но парсер почему то запоминает только последний вход <Text>....</Text>
Далее пример XML и PHP-скрипта.
Подскажите, что неправильно делаю?
<?xml version="1.0" encoding="windows-1251" ?>
<!DOCTYPE InfoPacket (View Source for full doctype...)>
- <InfoPacket>
<Source type="string">NewsBox</Source>
<Time type="datetime">12.07.2006 09:43:49</Time>
- <InfoItem>
<Source type="string">ПРАЙМ-ТАСС</Source>
<Time type="datetime">12.07.2006 09:43:49</Time>
<Title type="string">Цены на золото в Нью-Йорке во вторник достигли пятинедельного максимума</Title>
<Topic type="string">Биржи Банки Фонды</Topic>
<Author type="string">c</Author>
<Language type="string">RUS</Language>
<Option type="int" name="MessageId">2496</Option>
<Option name="TopicId" type="int">6</Option>
<Option name="Abstract" type="string">МОСКВА, 12 июля. /ПРАЙМ-ТАСС/. Фьючерсы на золото на торгах на COMEX /подразделении Нью-йоркской товарной биржи/ во вторник достигли самого высокого уровня за пять недель на фоне сообщений о взрывах на железной дороге в Индии, а также ввиду ослабления доллара США и роста цен на нефть. Об этом сообщает Dow Jones.</Option>
<Text>МОСКВА, 12 июля. /ПРАЙМ-ТАСС/. Фьючерсы на золото на торгах на COMEX /подразделении Нью-йоркской товарной биржи/ во вторник достигли самого высокого уровня за пять недель на фоне сообщений о взрывах на железной дороге в Индии, а также ввиду ослабления доллара США и роста цен на нефть. Об этом сообщает Dow Jones.</Text>
<Text>На закрытии торгов котировки августовских фьючерсов на золото выросли на 17 долларов до 643,10 долл за тройскую унцию. В ходе сессии котировки достигли пятинедельного максимума на уровне 643,90 долл, преодолев сопротивление на линии скользящей средней за 50 дней на отметке 640,40 долл.</Text>
<Text>Цены на золото стали расти в начале сессии в связи с ростом цен на рынке нефти, а также снижением доллара против евро. Затем появились сообщения о нескольких взрывах на железной дороге в индийском городе Мумбае, в результате которых погибло более 100 человек.</Text>
<Text>По словам Джорджа Джиро из RBC Capital Markets Global Futures, сообщения о взрывах спровоцировали рост цен на золото.</Text>
<Text>Кроме того, подорожание золота, было обусловлено техническими факторами, так как на рынок вернулись фонды.</Text>
<Text>"Покупательский интерес возрос – об этом свидетельствует появление новых участников на рынке", - сказал Джиро.</Text>
<Text>Цены на серебро также выросли. Сентябрьские фьючерсы на серебро достигли сессионного максимума на уровне 11,60 долл за унцию, вплотную приблизившись к сопротивлению на линии скользящей средней за 100 дней на отметке 11,664 долл.</Text>
<Text>Котировки сентябрьских фьючерсов на серебро завершили сессию с повышением на 44 цента на уровне 11,55 долл.</Text>
<Text>Котировки октябрьских фьючерсов на платину на закрытии торгов выросли на 23,30 долл до 1254 долл за унцию. Сентябрьские фьючерсы на палладий закрылись с повышением на 5,30 долл, на уровне 329 долл за унцию.</Text>
<Text>Итоги:</Text>
<Text>Вечерний фиксинг по золоту в Лондоне: 630,75 долл за унцию во вторник по сравнению с 626,00 долл в понедельник.</Text>
<Text>Цена на золото на рынке спот в США на 19.07 по Гринвичу: 642,55 долл за унцию, на 20,20 долл выше по сравнению с предыдущим днем, с диапазоном от 622,10 до 643,95 долл за унцию.</Text>
<Text>Цена фьючерса на золото на август /RGCQ06/: 643,10 долл за унцию /+17 долл/, с диапазоном от 631,80 до 643,90 долл за унцию.</Text>
<Text>Цена фьючерса на серебро на сентябрь /RSIU06/: 11,550 долл за унцию /+44 цента/, с диапазоном от 11,26 до 11,600 долл за унцию.</Text>
<Text>Цена фьючерса на платину на октябрь /RPLV06/: 1254 долл за унцию /+23,30 долл/, с диапазоном от 1238 до 1257,80 долл за унцию.</Text>
<Text>Цена фьючерса на палладий на сентябрь /RPAU06/: 329 долл за унцию /+5,30 долл за унцию/, с диапазоном от 324,80 до 329 долл за унцию.</Text>
</InfoItem>
</InfoPacket>
Скрипт:
<?php
$news = array(); // В этом массиве будут храниться новости,
// полученные из XML файла
$currentNews = null; // Текущая новость. Используется в процессе
// импорта данных
$index = null; // Текущий индекс в массиве новостей.
// Используется в процессе импорта данных
function saxStartElement($parser,$name,$attrs)
{
global $currentNews,$index;
switch($name)
{
case 'InfoPacket':
$news = array();
break;
case 'InfoItem':
$currentNews = array();
if (in_array('date',array_keys($attrs)))
$currentNews['date'] = $attrs['date'];
break;
default:
$index = $name;
break;
};
}
function saxEndElement($parser,$name)
{
global $news,$currentNews,$index;
if ((is_array($currentNews)) && ($name=='InfoItem'))
{
$news[] = $currentNews;
$currentNews = null;
};
$index = null;
}
function saxCharacterData($parser,$data)
{
global $currentNews,$index;
if ((is_array($currentNews)) && ($index))
$currentNews[$index] = $data;
}
$file = "C:\\htdocs\\news\\2496.xml";
$parser = xml_parser_create();
xml_set_element_handler($parser,'saxStartElement','saxEndElement');
xml_set_character_data_handler($parser,'saxCharacterData');
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,false);
$xml = join('',file('2496.xml'));
if (!xml_parse($parser,$xml,true))
die(sprintf('Ошибка XML: %s в строке %d',
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
xml_parser_free($parser);
print ("<table width='100%' border='1'>");
foreach($news as $n)
{
print ("<tr>");
print ("<td width='90%'><b>");
print($n['Title']);
print ("</b></td><td>");
print ($n['Time']);
print ("</td></tr>");
print ("<tr><td colspan='2'>");
print ($n['Text']);
print ("<br><br></td></tr>");
};
print ("</table>");
?>
Добрый день!
Помогите, что то я совсем запутался.
Есть xml в котором несколько полей <Text>...</Text>
Нужно его корректно прочитать парсеров для PHP, так чтобы и под FreeBSD и под Win работало.
Но парсер почему то запоминает только последний вход <Text>....</Text>
Далее пример XML и PHP-скрипта.
Подскажите, что неправильно делаю?
<?xml version="1.0" encoding="windows-1251" ?>
<!DOCTYPE InfoPacket (View Source for full doctype...)>
- <InfoPacket>
<Source type="string">NewsBox</Source>
<Time type="datetime">12.07.2006 09:43:49</Time>
- <InfoItem>
<Source type="string">ПРАЙМ-ТАСС</Source>
<Time type="datetime">12.07.2006 09:43:49</Time>
<Title type="string">Цены на золото в Нью-Йорке во вторник достигли пятинедельного максимума</Title>
<Topic type="string">Биржи Банки Фонды</Topic>
<Author type="string">c</Author>
<Language type="string">RUS</Language>
<Option type="int" name="MessageId">2496</Option>
<Option name="TopicId" type="int">6</Option>
<Option name="Abstract" type="string">МОСКВА, 12 июля. /ПРАЙМ-ТАСС/. Фьючерсы на золото на торгах на COMEX /подразделении Нью-йоркской товарной биржи/ во вторник достигли самого высокого уровня за пять недель на фоне сообщений о взрывах на железной дороге в Индии, а также ввиду ослабления доллара США и роста цен на нефть. Об этом сообщает Dow Jones.</Option>
<Text>МОСКВА, 12 июля. /ПРАЙМ-ТАСС/. Фьючерсы на золото на торгах на COMEX /подразделении Нью-йоркской товарной биржи/ во вторник достигли самого высокого уровня за пять недель на фоне сообщений о взрывах на железной дороге в Индии, а также ввиду ослабления доллара США и роста цен на нефть. Об этом сообщает Dow Jones.</Text>
<Text>На закрытии торгов котировки августовских фьючерсов на золото выросли на 17 долларов до 643,10 долл за тройскую унцию. В ходе сессии котировки достигли пятинедельного максимума на уровне 643,90 долл, преодолев сопротивление на линии скользящей средней за 50 дней на отметке 640,40 долл.</Text>
<Text>Цены на золото стали расти в начале сессии в связи с ростом цен на рынке нефти, а также снижением доллара против евро. Затем появились сообщения о нескольких взрывах на железной дороге в индийском городе Мумбае, в результате которых погибло более 100 человек.</Text>
<Text>По словам Джорджа Джиро из RBC Capital Markets Global Futures, сообщения о взрывах спровоцировали рост цен на золото.</Text>
<Text>Кроме того, подорожание золота, было обусловлено техническими факторами, так как на рынок вернулись фонды.</Text>
<Text>"Покупательский интерес возрос – об этом свидетельствует появление новых участников на рынке", - сказал Джиро.</Text>
<Text>Цены на серебро также выросли. Сентябрьские фьючерсы на серебро достигли сессионного максимума на уровне 11,60 долл за унцию, вплотную приблизившись к сопротивлению на линии скользящей средней за 100 дней на отметке 11,664 долл.</Text>
<Text>Котировки сентябрьских фьючерсов на серебро завершили сессию с повышением на 44 цента на уровне 11,55 долл.</Text>
<Text>Котировки октябрьских фьючерсов на платину на закрытии торгов выросли на 23,30 долл до 1254 долл за унцию. Сентябрьские фьючерсы на палладий закрылись с повышением на 5,30 долл, на уровне 329 долл за унцию.</Text>
<Text>Итоги:</Text>
<Text>Вечерний фиксинг по золоту в Лондоне: 630,75 долл за унцию во вторник по сравнению с 626,00 долл в понедельник.</Text>
<Text>Цена на золото на рынке спот в США на 19.07 по Гринвичу: 642,55 долл за унцию, на 20,20 долл выше по сравнению с предыдущим днем, с диапазоном от 622,10 до 643,95 долл за унцию.</Text>
<Text>Цена фьючерса на золото на август /RGCQ06/: 643,10 долл за унцию /+17 долл/, с диапазоном от 631,80 до 643,90 долл за унцию.</Text>
<Text>Цена фьючерса на серебро на сентябрь /RSIU06/: 11,550 долл за унцию /+44 цента/, с диапазоном от 11,26 до 11,600 долл за унцию.</Text>
<Text>Цена фьючерса на платину на октябрь /RPLV06/: 1254 долл за унцию /+23,30 долл/, с диапазоном от 1238 до 1257,80 долл за унцию.</Text>
<Text>Цена фьючерса на палладий на сентябрь /RPAU06/: 329 долл за унцию /+5,30 долл за унцию/, с диапазоном от 324,80 до 329 долл за унцию.</Text>
</InfoItem>
</InfoPacket>
Скрипт:
<?php
$news = array(); // В этом массиве будут храниться новости,
// полученные из XML файла
$currentNews = null; // Текущая новость. Используется в процессе
// импорта данных
$index = null; // Текущий индекс в массиве новостей.
// Используется в процессе импорта данных
function saxStartElement($parser,$name,$attrs)
{
global $currentNews,$index;
switch($name)
{
case 'InfoPacket':
$news = array();
break;
case 'InfoItem':
$currentNews = array();
if (in_array('date',array_keys($attrs)))
$currentNews['date'] = $attrs['date'];
break;
default:
$index = $name;
break;
};
}
function saxEndElement($parser,$name)
{
global $news,$currentNews,$index;
if ((is_array($currentNews)) && ($name=='InfoItem'))
{
$news[] = $currentNews;
$currentNews = null;
};
$index = null;
}
function saxCharacterData($parser,$data)
{
global $currentNews,$index;
if ((is_array($currentNews)) && ($index))
$currentNews[$index] = $data;
}
$file = "C:\\htdocs\\news\\2496.xml";
$parser = xml_parser_create();
xml_set_element_handler($parser,'saxStartElement','saxEndElement');
xml_set_character_data_handler($parser,'saxCharacterData');
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,false);
$xml = join('',file('2496.xml'));
if (!xml_parse($parser,$xml,true))
die(sprintf('Ошибка XML: %s в строке %d',
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
xml_parser_free($parser);
print ("<table width='100%' border='1'>");
foreach($news as $n)
{
print ("<tr>");
print ("<td width='90%'><b>");
print($n['Title']);
print ("</b></td><td>");
print ($n['Time']);
print ("</td></tr>");
print ("<tr><td colspan='2'>");
print ($n['Text']);
print ("<br><br></td></tr>");
};
print ("</table>");
?>