精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● PHP>>问题解答>>[转载]XML How-to

主题:[转载]XML How-to
发信人: 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]

[关闭][返回]