发信人: jackyz()
整理人: dalasthunder(2002-07-25 06:09:10), 站内信件
|
XML How-to
作者:Joe Stump
翻译:limodou
最近,公司交给我一项学习XML的任务。OK,但它不是技术上的XML,而是RD F。但是我发现PHP中的XML分析函数同样可以工作。我分析的是DMOZ(http://www .dmoz.org/),但是为了简单,我将只使用XML的基本东西,在你的时间里,自由 去分析DMOZ ;o)
开始之前,先要确定你所拥有的PHP二进制执行码编译时是带'--with-xml'选 项的。如果是这样的,你就可以开始分析XML了。接着从Slashdot的主页上抓取X ML文件(http://www.slashdot.org/slashdot.xml)。Slashdot有一个相当简单的 文件,非常容易分析。
记住对XML的处理很象处理数据库中的表。你会得到xml分析器的一个结果索 引,象是XML文档的一个"假"表。一旦清楚了不同之处,就可以立刻开始分析了。
PHP的XML函数允许你指定三个函数,用来处理XML文件中的数据。一个函数用 来处理开标记,一个处理两个标记之间的数据,另一个处理闭标记。根据传给你 的标记的名字,你就可以按照意愿操作数据了。为了开始,需要查看XML文件,找 出文件中的标记。在slashdot文件中,包含有STORY,TITLE,URL,TIME,AUTHO R,DEPARTMENT,TOPIC,COMMENTS,SECTION和IMAGE标记。在某种情况下可能还 有一些属性,例如HREF在HTML中是A标记的属性。PHP有一种非常“酷”的方法来 自动地处理属性。接着需要在脚本中定义这些标记。
<?php
$open_tags = array(
'STORY' => '<STORY>',
'TITLE' => '<TITLE>',
'URL' => '<URL>');
$close_tags = array(
'STORY' => '</STORY>',
'TITLE' => '</TITLE>',
'URL' => '</URL>');
?>
我只想分析上面的数据,因为我只想处理这些Slashbox其中之一。在列表的 后面是用来提取数据的函数。下面就是我所创建的函数。
<?php
// 处理开标记的属性
// $attrs 是一个多维数组,以属性名为键值,值为它的属性值
function startElement($parser, $name, $attrs=''){
global $open_tags, $temp, $current_tag;
$current_tag = $name;
if ($format = $open_tags[$name]){
switch($name){
case 'STORY':
echo 'New Story: ';
break;
default:
break;
}
}
}
// $current_tag 用来表示当前正在处理的标记,
// 后面将在characterData函数中使用
//
// 当看到一个</STORY>标记时,这时就应该输出临时变量
// 并且准备转移到下一个标记
function endElement($parser, $name, $attrs=''){
global $close_tags, $temp, $current_tag;
if ($format = $close_tags[$name]){
switch($name){
case 'STORY':
return_page($temp);
$temp = '';
break;
default:
break;
}
}
}
// 在两个元素间的数据将传给这个函数,
// 那么在<TITLE>Title Here</TITLE>这行中,
// $data将等于'Title Here'
function characterData($parser, $data){
global $current_tag, $temp, $catID;
switch($current_tag){
case 'TITLE':
$temp['title'] = $data;
$current_tag = '';
break;
case 'URL':
$temp['url'] = $data;
$current_tag = '';
break;
default:
break;
}
}
?>
如你所见,到目前为止用PHP分析XML一切很顺利。下面是有趣的部分 -- 分 析文件!要对文件进行分析,需要剩下的代码,它们相当简单。
<?php
function return_page(){
global $temp;
echo 'o <A HREF="'.$temp['url'].'">'.$temp['title'].'<BR>';
}
// 我们正在分析什么?
$xml_file = 'slashdot.xml';
// 声时字符集 - 缺省为UTF-8
$type = 'UTF-8';
// 创建分析器
$xml_parser = xml_parser_create($type);
// 设置一些分析选项
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, 'UTF-8' );
// 告诉PHP,当找到一个标记时应该调用哪一个函
// 数,而且这些函数也会处理元素的属性
xml_set_element_handler($xml_parser, 'startElement','endElement');
// 告诉PHP,用哪一个函数来处理字符数据
xml_set_character_data_handler($xml_parser, 'characterData');
if (!($fp = fopen($xml_file, 'r'))) {
die("Could not open $xml_file for parsing!\n");
}
// 循环处理文件
while ($data = fread($fp, 4096)) {
if (!($data = utf8_encode($data))) {
echo 'ERROR'."\n";
}
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf( "XML error: %s at line %d\n\n",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser);
?>
现在发生了这些事情:PHP开始处理,直到它找到<ELEMENT ATTRIBUTE='bol d'>。然后将ELEMENT和它的属性传给startElement函数。因为Slashdot文件没有 任何属性,所以不必担心。但是如果文件有属性,应该在这里处理它们。然后PH P将闭元素与开元素之间的数据传给characterData函数,最后将闭元素和它的属 性传给endElement函数。endElement函数调用了return_page()函数,但是只有当 碰到故事结束时才会调用。在这个时候,$temp变量保存着从startElement和cha racterData所收集来的数据。
现在最后要做的就是在cron[注1]中加入一条wget了!
-----------------------------------------------------------------
[注1]
cron是在unix/linux中自动定时处理守护,可以将一些想定时处理的工作交给它 来完成。详细的请参阅unix/linux手册。
转自:PHPBuilder.com
-----------------------------------------------------------------
转载自:[http://www.phprecord.com/]
原文由:[limodou]翻译.
(limodou出品,必属佳品 :o)
-- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 61.141.206.125]
|
|