当前位置:Linux教程 - Php - php中xml操作指南

php中xml操作指南

PHP中XML操作指南
最近因为工作原因我需要学习XML, 但并不是纯技术上的XML, 而是RDF,但是我发现PHP的XML解析函数功能是一样的。我需要解析DMOZ(http://www.dmoz.org),但是出于简单性考虑我会专注于XML的基本原理,将解析DMOZ的留给你在业余时间去完成。 ;o

首先你需要确定你的PHP编译是包括'--with-xml'选项的,然后你就可以开始解析XML了。下面要抓取Slashdot的XML文件, 位置是 http://www.slashdot.org/slashdot.xml。 Slashdot的文件比较简单,易于分析。

记住操作XML文件就象操作数据库中的表。XML解析器包含结果索引,XML文档则包含伟表,一旦你明确了这种差别就不需要花费太多时间了。

PHP的XML函数允许你使用三个函数来操作XML文件中的数据:一个操作开始标记,一个操作标记间的数据, 一个操作结束标记。基本传送的标记名称,你以后可以自由的操作数据。 你先需要研究一下XML文件内容,看看包括哪些标记。 我们的Slashdot文件中包括STORY, TITLE, URL, TIME, AUTHOR, DEPARTMENT, TOPIC, COMMENTS, SECTION和IMAGE标记。有些标记包含属性值,例如HREF是标记A的一个属性, PHP有很优秀的方法来自动处理属性值。 下面我们在脚本中定义这些标记。

———— PHP代码 ————

<?php

$open_tags
= array(
    
'STORY' => '<STORY>',
    
'TITLE' => '<TITLE>',
    
'URL' => '<URL>');

$close_tags = array(
    
'STORY' => '</STORY>',
    
'TITLE' => '</TITLE>',
    
'URL' => '</URL>');
?>   

————————————

我只想分析上面的这些数据,因为我只需要一些很酷的Slash框子。 下面就是定义函数来提取数据:

———— PHP代码 ————

<?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
'新的故事: ';
        break;
        default:
        break;
    }
    }
}

// $current_tag告诉我们正在处理的标记,我们随后会在characterData函数中使用
//
// 当遇到</STORY>标记时我们知道要flush所有的临时变量准备操作下一个标记
[php]
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代码 ————

<?php

function return_page(){
    global
$temp;
    echo
'o <A HREF="'.$temp['url'].'">'.$temp['title'].'</A><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(
"无法打开 $xml_file 文件进行解析!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 %dnn",
        
xml_error_string(xml_get_error_code($xml_parser)),
        
xml_get_current_line_number($xml_parser)));
    }
}

xml_parser_free($xml_parser);

?>   

————————————

所发生的情况是:PHP开始解析,直到遇到<ELEMENT ATTRIBUTE='bold'>,然后传送ELEMENT和其属性给startElement函数。 因为Slashdot的文件并不包含属性,我们不需要关心这一步,但是如果有属性, 就是这样的情况。然后传送起止元素间的数据给characterData函数,最后传送结束元素及其属性给endElement函数。endElement函数调用return_page()函数, 但是是在发现已经到达数据的结尾时。直到此刻$temp变量才包含startElement和characterData函数收集的数据。

下面所要做的就只是在你的cron操作里面加入wget!