pdf
|<<
<
>
>>|
/
XML in the real world ---- {{#x|XML}} in the {{#ci|real}} world 真实世界中的{{#x|XML}} ☺{{#author|agentzh}}☺ {{#author|(章亦春)}} {{#date|2006.10}} ---- ♡ {{#x|RSS}} is {{#ci|cool}}! RSS 很酷哦! ---- RSS ➥ {{#x|R}}eally {{#x|S}}imple {{#x|S}}yndication ---- {{#ci|Tired}} of {{#x|checking}} your favorite news and blogs sites everyday? 厌倦了每天去查看你最喜爱的 那些新闻和博客网站了吧? ---- Let me tell you how {{#x|RSS}} can {{#ci|save}} you. 让我来告诉你 如何让 RSS 拯救你。 ---- Open {{#x|Google Reader}}: the {{#ci|first}} thing that I do everyday. 打开 Google Reader: 我每天做的第一件事情。 ---- {{img src="#" width="0" height="0"}} {{img src="images/reader.png" width="834" height="595"}} ---- Let's read chromatic's {{#ci|latest}} journals in {{#x|Google Reader}}... 让我们在 Google Reader 中阅读 chromatic 最近的日记…… ---- {{img src="images/reader_c.png" width="808" height="498"}} ---- Let's take a look at the {{#ci|original}} journal item on the {{#x|use.perl.org}} site... 让我们来看看 use.perl.org 站点上的原始日记…… ---- {{img src="images/useperl_c.png" width="806" height="559"}} ---- Now let's turn to the {{#ci|latest}} Pugs blog posts in {{#x|Google Reader}}... 现在让我们在 Google Reader 中转向新的 Pugs 博客文章…… ---- {{img src="images/reader_pugs.png" width="870" height="583"}} ---- The {{#ci|original}} post I published onto the {{#x|pugs.blogs.com}} site... 我最初发布在 use.perl.org 站点上的帖子…… ---- {{img src="images/pugs.png" width="815" height="591"}} ---- The {{#x|XML}} magic {{#ci|behind}} the curtain... 幕后的 XML 魔法…… ---- {{img src="images/subs_list.png" width="776" height="508"}} ---- {{#x|RSS feed}} for {{#ci|chromatic}}'s journals... chromatic 的日记的 RSS 反馈…… ---- {{img src="images/useperl_rss.png" width="748" height="527"}} ---- {{#x|RSS}} feed for our {{#ci|Pugs}} blog site... Pugs 博客站点的 RSS 反馈…… ---- {{img src="images/pugs_rss.png" width="775" height="575"}} ---- ♡ {{#x|AJAX}}, our {{#ci|good}} friends! AJAX,我们的好朋友! ---- AJAX ➥ {{#x|A}}synchronous {{#x|JA}}vaScript and {{#x|X}}ML ---- ☺ Let's open {{#ci|Cherry}}'s {{#x|Qzone blogs}}... 让我们打开 Cherry 的 Qzone 博客…… ---- {{img src="images/cherry_home.png" width="799" height="569"}} ---- ☺ {{#ci|Click}} one of the articles and {{#x|enter}} it... 点击其中的一篇文章进入…… ---- {{img src="images/cherry_post.png" width="800" height="569"}} ---- What happened {{#ci|behind the curtain}} when we're performing these {{#x|actions}}? 在我们执行这些动作的时候, 幕后都发生了哪些事情? ---- Here is the underlying {{#x|HTTP traffic}} between the {{#ci|Qzone site}} and my {{#ci|IE browser}} recorded by {{#x|HTTP::Proxy}}... 这里有 HTTP::Proxy 模块记录下的 Qzone 站点与我的 IE 浏览器之间 的底层 HTTP 通信…… ---- {{#cm|[16:04:56]}} GET http://u13.qzone.qq.com/cgi-bin/cgi_client_entry.cgi?uin=11854905 {{#cm|[16:05:40]}} GET http://u13.qzone.qq.com/proxy.html ... {{#cm|[16:09:37]}} GET {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/blog_signature.cgi?uin=11854905}} {{#cm|[16:10:00]}} GET {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/blog_get_category.cgi?}} {{#kw|uin=11854905}} {{#cm|[16:10:00]}} GET http://imgcache.qq.com/qzone/proxy.vbs {{#cm|[16:10:02]}} GET {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?}} {{#kw|uin=11854905&blogid=39&flag=0}} {{#cm|[16:10:04]}} GET {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?}} {{#kw|uin=11854905&blogid=39&archive=-2}} ... ---- {{#ci|Most}} of the {{#x|HTTP requests}} were initiated by the {{#x|JavaScript}} code running in your {{#ci|web browser}}. 这些 HTTP 请求中的大部分是由 运行在你的网络浏览器中的 JavaScript 代码发起的。 ---- Let's {{#ci|check}} some of the {{#x|HTTP requests}} by hand... 让我们来手工查看一下 其中的几个 HTTP 请求…… ---- {{#x|XML data}} for Cherry's {{#ci|signature}} Cherry 的个性签名所对应的 XML 数据 ➥ {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/}} {{#kw|blog_signature.cgi?uin=11854905}} ---- {{img src="images/signature.png" width="829" height="212"}} ---- {{#x|XML data}} for Cherry's article {{#ci|category}} list Cherry 的文章类别列表所对应的 XML 数据 ➥ {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/}} {{#kw|blog_get_category.cgi?uin=11854905}} ---- {{img src="images/category.png" width="599" height="387"}} ---- {{#x|XML data}} for the {{#ci|title}} of Cherry's 40th post (with ID 39) Cherry 的第 40 篇帖子(标识为 39)的{{#x|标题}} 所对应的 XML 数据 ➥ {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?}} {{#kw|uin=11854905&blogid=39&flag=0}} ---- {{img src="images/title.png" width="695" height="394"}} ---- {{#x|XML data}} for the {{#ci|body and comments}} of Cherry's 40th post (with ID 39) Cherry 的第 40 篇帖子(标识为 39)的{{#x|正文及评论}} 所对应的 XML 数据 ➥ {{#kw|http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?}} {{#kw|uin=11854905&blogid=39&archive=-2}} ---- {{img src="images/body.png" width="733" height="544"}} ---- Our {{#x|web browser}} renders these {{#x|XML data}} files using {{#x|HTML templates}} sent by the Qzone server, and generates the final {{#x|HTML source}}. 我们的网络浏览器根据 Qzone 服务器 传过来的 HTML 模板对这些 XML 数据进行渲染, 生成最终的 HTML 源码。 ---- {{#x|XML data}} + {{#kw|HTML templates}} = {{#cm|final HTML source}} XML 数据 + HTML 模板 = 最终的 HTML 源码 ---- The {{#ci|whole}} process happens in our {{#x|web browser}}. 整个过程都发生在我们的浏览器内部。 ---- But {{#ci|where}} are the {{#x|HTML templates}}? 但是 HTML 模板究竟在哪里呢? ---- Let's check the {{#ci|raw}} HTML source sent from the Qzone {{#x|server}} 让我们来看看 Qzone 服务器 传过来的原始 HTML 源码 ---- {{img src="images/check_html.png" width="761" height="564"}} ---- ... <!-- 日志//--> <div id=\"tpl_blog_b\" class=\"mode_table\" style=\"display:none\">... <table cellSpacing=\"0\" cellpadding=\"0\" width=\"100%\" class= ... {{#x|[%repeat_0 match="/rss/channel/item" repeat_num="10"%]}} <tr><td class=\"index_blog_btd\"> [<a href=\"#\" onclick=\"openCategory(\'{{#x|[%=@type%]}}\');return false\" ...title=\"点击进入分类\">{{#x|[%=@category%]}}</a>] <a href=\"#\" title=\"{{#x|[%=@title%]}} -- 发表于 {{#x|[%=@pubTimeString%]}}\" onClick=\"openBlog(\'{{#x|[%=@archive%]}}\',\'{{#x|[%=@id%]}}\');return false\"> ... </a></td> <td class=\"info\">评论(<span class=\"hit\">{{#x|[%=@comment%]}}</span>)</td> {{#x|[%_repeat_0%]}} </table> </div> ... ---- You see, it's a {{#ci|client}}-side HTML {{#x|template}}! {{#kw|☼}} 你看, 这是一个客户端的 HTML 模板! ---- It's the {{#x|JavaScrip code}} that {{#ci|grabs}} the {{#x|XML data}} from the web and fills it into the {{#x|HTML templates}} automatically, resulting in the final appearance we see in the browser. 所以是 JavaScript 代码自动从网上获取 XML 数据并将之填入到 HTML 模板中,最 终得到我们在浏览器中看到的效果。 ---- Then {{#x|why can't}} we do XML data grabbing {{#ci|ourselves}}? 那么为什么我们就不可以自己去 攫取 XML 数据呢? ---- For example, we can obtain the {{#x|data}} for {{#x|all}} of Cherry's articles by simply changing the {{#x|URL}}! 比如,我们可以通过简单地修改网址 得到的有文章的数据! ---- http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?uin=11854905&{{#x|blogid=39}}&flag=0 +http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?uin=11854905&{{#x|blogid=38}}&flag=0 +http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?uin=11854905&{{#x|blogid=37}}&flag=0 +http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?uin=11854905&{{#x|blogid=36}}&flag=0 +http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?uin=11854905&{{#x|blogid=35}}&flag=0 +... http://b1.qzone.qq.com/cgi-bin/blog/blog_one_title.cgi?uin=11854905&{{#x|blogid=0}}&flag=0 ---- http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?uin=11854905&{{#x|blogid=39}}&archive=-2 +http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?uin=11854905&{{#x|blogid=38}}&archive=-2 +http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?uin=11854905&{{#x|blogid=37}}&archive=-2 +http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?uin=11854905&{{#x|blogid=36}}&archive=-2 +http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?uin=11854905&{{#x|blogid=35}}&archive=-2 +... http://b1.qzone.qq.com/cgi-bin/blog/blog_commentlist.cgi?uin=11854905&{{#x|blogid=0}}&archive=-2 ---- It means that... now we can {{#ci|directly}} access Qzone's {{#x|database}}, completely {{#ci|bypassing}} its cumbersome HTML interface! 这意味着…… 现在我们可以直接访问 Qzone 的数据库 完全绕过它那笨重的 HTML 界面! ---- Let's write a tiny {{#x|Perl}} {{#ci|script}} to do {{#ci|all}} these tricks for us! 让我们来编写一个小小的 Perl 脚本来为我们实现所有这些把戏。 ---- {{img src="images/getqzone.png" width="667" height="334"}} ---- One {{#x|sample output}} of the program for {{#ci|Cherry}}'s Blogs ➥ {{http://perlcabal.org/agent/cherry.html}} 该程序针对 Cherry 的博客的一次典型输出 ---- {{img src="images/qzone_html.png" width="802" height="593"}} ---- {{img src="images/qzone_html2.png" width="802" height="593"}} ---- This program uses {{#x|LWP::UserAgent}} to {{#ci|get}} the XML data directly from the web and uses {{#x|XML::Simple}} to {{#ci|parse}} it. 该程序使用 LWP::UserAgent 模块 直接从网上获取 XML 数据,并利用 XML::Simple 解析之。 ---- {{#ci|No}} need for Audrey's {{#x|Template::Extract}} to {{#ci|extract}} data from the HTML source. That is the {{#ci|power}} of {{#x|AJAX}} and {{#x|XML}}! 不再需要唐凤的 Template::Extract 模块来 从 HTML 源码中提取数据。 这就是 AJAX 和 XML 的威力! ---- Get the {{#x|slides}} today! {{#c|♨}} {{http://agentzh.org/misc/slides/xmlapp.pdf}} ---- {{#c|Thank you!}} ☺