作者:csdn 来源:csdn 2008年2月1日
关键字: Linux
看到的内容并不多,但是我希望这个示例尽量简单。主要是因为后面的内容不容易处理。
提供XML接口的一个主要原因是人们不必编写清单3所示的代码。
清单 3. fetch.rb
require 'net/http'
articles = []
Net::HTTP.start('localhost', 80) { |http|
response = http.get('/ws/articles.php')
body = response.body
body.scan( /(<div class="title">.*?)<br\/>/m ) { |item|
title = item[0].scan( /<div class="title">(.*?)<\/div>/ )
author = item[0].scan( /<div class="author">(.*?)<\/div>/ )
description = item[0].scan( /<div class="description">(.*?)<\/div>/ )
title = title[0][0] if ( title[0].length > 0 )
author = author[0][0] if ( author[0].length > 0 )
description = ( description.length > 0 ) ? description[0][0] : ''
articles.push( { :title => title,
:author => author, :description => description } )
}
}
p articles
这是基于Ruby的“屏幕截取器”。这个脚本以一个大文本字符串获取页面,然后使用一组复杂的正则表达式解析页面的标题、作者和描述元素。
在命令行运行时,将看到清单4所示的代码。
清单4. 运行fetch.rb
% ruby fetch.rb
[{:author=>"Megan Herrington", :description=>"Everything that I love about dogs I
learned in preschool", :title=>"What I like about dogs"}, {:author=>"Jack
Herrington", :description=>"How to script, produce and direct Hong Kong action
flicks", :title=>"Making action movies"}, {:author=>"Lori Herrington",
:description=>"Everything you need to know to win at Paper Mario", :title=>"Super
Paper Mario Tips"}, {:author=>"Oso Herrington", :description=>"", :title=>"Why I
bark"}]
是的,它获得了数据,但是不能获得这些元素的ID,因为HTML没有ID。
您可能想知道为什么我选择使用Ruby实现。这主要是因为它很酷,并且易于阅读,可是这里却看不到这些优点。但这不是Ruby的错。屏幕截取器本身就很复杂。它们难于编写、易于出错、难以维护,即使对接口的HTML稍加修改就可能崩溃。本文中的所有屏幕截取器代码都只有一个目的:说服您对数据设置XML接口。如果您的数据很有趣,人们就能通过某种途径找到它。如果您不支持XML,当您更新站点以“美化”界面时,就会获得屏幕截取,并且触怒客户。
添加XML服务
因此,为了避免屏幕截取问题,并制作一些炫酷的程序来使用我们的数据,我将对表格编写一个XML接口,如清单5所示。
清单5. artxml.php
<?php
require_once( "DB.php" );
$db =& DB::Connect( 'mysql://root@localhost/articles1', array() );
if (PEAR::isError($db)) { die($db->getMessage()); }
$dom = new DomDocument();
$dom->formatOutput = true;
$root = $dom->createElement( "articles" );
$dom->appendChild( $root );
$res = $db->query( "SELECT * FROM articles" );
$rows = array();
while( $res->fetchInto($row, DB_FETCHMODE_ASSOC) ) {
$art = $dom->createElement( "article" );
$art->setAttribute( 'id', $row['id'] );
$root->appendChild( $art );
$title = $dom->createElement( "title" );
$title->appendChild( $dom->createTextNode( $row['title'] ) );
$art->appendChild( $title );
$author = $dom->createElement( "author" );
$author->appendChild( $dom->createTextNode( $row['author'] ) );
$art->appendChild( $author );
$desc = $dom->createElement( "description" );
$desc->appendChild( $dom->createTextNode( $row['description'] ) );
$art->appendChild( $desc );
}
header( "Content-type: text/xml" );
echo $dom->saveXML();
?>
在命令行运行此脚本时,将获得清单6所示的输出。
清单6. 文章XML
% php artxml.php
<?xml version="1.0"?>
<articles>
<article id="1">
<title>What I like about dogs</title>
<author>Megan Herrington</author>
<description>Everything that I love about dogs I learned in
preschool</description>
</article>
<article id="2">
<title>Making action movies</title>
<author>Jack Herrington</author>
<description>How to script, produce and direct Hong Kong action
flicks</description>
</article>
...
这非常直观。有一个根文章标记,它包含一组文章标记。每个文章标记都有id属性(包含记录的数字id),以及存储相应数据的作者和描述标记。
我使用了PHP中的XML文档对象模型(Document Object Model,DOM)功能,而不是手动编写标记。这样DOM将为我处理所有XML节点平衡和编码工作。这是确保页面返回的XM总是有效的简便方式。强烈推荐使用XML DOM功能来输出XML。所有主要的web语言都支持构建和导出XML DOM。
获取XML