XML 观察: Planet Blog

XML 观察: Planet Blog 英文原文
内容:
Planet RDF
RSS 提要的源代码清单
RSS 解析器
聚集
运行软件
结束语
参考资料
关于作者
对本文的评价
相关内容:
追溯 RDF 数据的源头
使用 XML 和 RDF 找到朋友
使用 FOAF 支持在线社区
RSS 2.0 内容提要
在 XML 专区还有:
教学
工具与产品
所有的文章
让开发团体走到一起

级别:入门

Edd Dumbill (edd@xml.com)
编辑兼发行人,xmlhack.com
2004 年 2 月

Column iconEdd Dumbill 解释了 weblog 中的 RSS 提要是如何聚集起来的,从而增强软件开发人员小组之间的交流,以及如何使用 XML/RDF 来描述多个社区。

Blogging 是有趣的。weblog 是主页和个人杂志的混合物,已经成为人们在 Web 上表达自己的最流行方式。它是随着 RSS 的发展而产生的(对于 RSS 这个缩写的全称是有分歧的,可以是 RDF Site Summary ( RDF 站点摘要)或者 Really Simple Syndication (真正简单的连锁))。无论是直接面向桌面 RSS 阅读器,还是 Blogdex、Meerkat 或者 Bloglines 这样的聚集 Web 网站,RSS 最广泛的应用之一是 weblog 条目的连锁。

关于 RSS,在 Web 上有很多地方都已经写过了。如果您对它还不太熟悉,请参阅 参考资料 里提供的链接。实际上,我在这个专栏中写过关于使用 Redland RDF 工具包 的文章,其中的示例代码就是 RSS 1.0 提要的一个简单聚集器。

正如我提到的,用个人聚集器处理 RSS 提要是一种很普遍的方法。Straw (请参阅 参考资料)就是非常典型的类型,图 1 是它的一张截图。能选择您所需要的 RSS 提要的好处是,最终得到的信息非常符合您的喜好。但是它的坏处是,最终得到的信息非常符合您的喜好:您不会看到任何超出您选择范围的东西!

图 1. GNOME 桌面平台的个人 RSS 聚集器 Straw 的截图
图 1. GNOME桌面平台的个人 RSS 聚集器 Straw 的截图

最近,越来越多为开放源代码项目工作的开发人员拥有了他们自己的 weblog。一般来说,这些开发人员对写代码的兴趣要比更新网页大得多。由于像 pybloxsom 和 Movable Type 之类快速 blogging 工具的广泛使用,他们已经被 blogging 所吸引。也有很多自由软件的开发人员暂时在使用 Advogato(请参阅 参考资料)。Advogato 有一个日志系统,这个系统的发展趋势是想让用户对自己的内容和表示方式有更多的控制权。

阅读那些相关项目的开发者杂志,对您在工作中保持进步、设计决策以及把握机遇都是有益的。建立一个会话,激活并激励一个开发者社区,不然他们只会非常松散地组织在一起。不难发现,在所有的类型的大中型组织中都使用了这种方法。

然而,想要通过个人聚集器来跟踪这些杂志需要一点运气:因为新的使用者会把您想要跟踪的信息源和其他消息源混杂在一起,除非您的 RSS 聚集器中只有固定的使用者,但那样的话您的社区就不会再有新面孔出现了。如果您能以组为单位访问这些杂志,会比为每个个人的提要搜索一遍要好得多。

由于这个原因,再加上想要尽量给出围绕在开放源代码项目周围的社区的更多感受,聚集开发人员的 weblog 的 Web 站点开始出现了。最早的例子是 Planet GNOME,它的成员中既有 Red Hat 和 Novell/Ximian 这样的企业,也有很多自由开发人员。接着是 Monologue,Novell/Ximian 有一个负责 .NET 运行时和 C# 编译器的项目 Mono,Monologue 就是由这个项目的开发人员的 weblog 组成的(请参阅 参考资料)。

Planet RDF
受这些正在不断涌现各种社区杂志的鼓动,我把几个跟我一样对 RDF 和语义 Web 技术感兴趣的朋友拉到了一起,打算建一个类似的网站,内容为语义 Web 技术。这个网站叫 Planet RDF,您可能会喜欢通过查看它来阅读杂志。图 2 是这个 Web 网站的截图。

图 2. Planet RDF 的截图
图 2. Planet RDF 的截图

毫不奇怪,Planet RDF 是完全由 XML 和 RDF 技术构建的。文章的剩余部分要讨论这个聚集器的架构、配置文件的格式,以及怎样设置一个供自己使用的聚集器。

这种聚集器要求具备的条件相对比较少:

  • 一个想要聚集的 RSS 提要的清单
  • 一个 RSS 解析器
  • 一个条目数据库
  • 一种提取和格式化聚集结果的方法

由于很多人很慷慨地把他们精彩网页的代码共享出来,这里的大多数组件都已经是现成的了。出于不同的目的,Matt Biddulph 在 2003 年的早些时候编写了 RSS 聚集器。因为有太多现成的东西,这个网站的建立和投入运行只需要花费开发小组(Matt Biddulph、Dave Beckett 和 Phil McCarthy)3个小时的时间,全部的工作就只是使用一下 XSLT 和 CSS 而已!下面我将依次叙述每个组件。

RSS 提要的源代码清单
为了建立一个像 Planet RDF 这样的网站,每个成员都需要提供如下信息:

  • 姓名
  • weblog 的 URL
  • weblog 中 RSS 提要的 URL
  • weblog 的标题

我们应该获取 Dave Beckett 的 Semantic Web weblogs (请参阅 参考资料)清单,然后把它输入聚集器,用 XSLT 进行转换。

weblog (有的地方称为 blogroll )中 RSS 提要的清单格式已经出现了,称为 Outline Processor Markup Language (概要处理标记语言,OPML)(请参阅 参考资料)。但是这个格式只能支持一个标题和一个 URL ,所以它不能真正满足现有的任务。实际上,请注意到所需要的很多元数据元素,和 Friend of a Friend (FOAF) 词汇表中的元素都是相同的,因此我们建立了清单 1 中所显示的格式。简短起见,这里只列出了两个成员。

清单 1. RSS 提要的源代码清单

    <rdf:RDF
           xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
           xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
           xmlns:foaf="http://xmlns.com/foaf/0.1/"
           xmlns:rss="http://purl.org/rss/1.0/"
           xmlns:dc="http://purl.org/dc/elements/1.1/">

    <foaf:Group>
      <foaf:name>Planet RDF</foaf:name>
      <foaf:homepage rdf:resource="http://planetrdf.com/" />
      <rdfs:seeAlso rdf:resource="http://planetrdf.com/bloggers.rdf" />

      <foaf:member>
        <foaf:Person>
          <foaf:name>Joe Bloggs</foaf:name>
          <foaf:weblog>
            <foaf:Document rdf:about="http://foo.com/blog/">
              <dc:title>Joe Bloggs' Blog</dc:title>
              <rdfs:seeAlso>
                <rss:channel rdf:about="http://foo.com/blog/blog.rdf" />
              </rdfs:seeAlso>
            </foaf:Document>
          </foaf:weblog>
        </foaf:Person>
      </foaf:member>

      <foaf:member>
        <foaf:Person>
          <foaf:name>Frederique Smith</foaf:name>
          <foaf:weblog>
            <foaf:Document rdf:about="http://bar.com/blog/">
              <dc:title>Freddie's Blog</dc:title>
              <rdfs:seeAlso>
                <rss:channel rdf:about="http://bar.com/blog/blog.rss" />
              </rdfs:seeAlso>
            </foaf:Document>
          </foaf:weblog>
        </foaf:Person>
      </foaf:member>

    </foaf:Group>
  </rdf:RDF>

清单 1 中,虽然在用 XML 表示时增加了一些 RDF 特有的冗余信息,但还是可以很方便地用通用的 XML 工具进行处理,例如 XPath/XSLT。请注意在文档中清楚地定义了组成员身份的语义:不能和任何已有的 URL 重复!

这样使用 RDF 的好处之一,是它可以在保证向后兼容其他 RDF 处理的情况下,扩展其他的功能。(如果想要了解我为什么会认为这是一种奇妙的事物,可以参阅 参考资料 中我的一篇文章“Sticking with it -- RDF”。)清单 2 显示了我们将来可能想要做的一些修改,但是都不会影响任何针对低版本格式编写的 RDF 感知的软件。

清单 2. 怎样扩展源代码清单的例子

<foaf:member>
  <foaf:Person>
   <foaf:name>Joe Bloggs</foaf:name>

<!-- Joe's homepage -->
<foaf:homepage rdf:resource="http://foo.com/~joe/" />

<!-- a picture of Joe, to put by each of his entries -->
<foaf:img rdf:resource="http://foo.com/~joe/me.jpg" />

   <foaf:weblog>
    <foaf:Document rdf:about="http://foo.com/blog/">
     <dc:title>Joe Bloggs' Blog</dc:title>
     <rdfs:seeAlso>
      <rss:channel rdf:about="http://foo.com/blog/blog.rdf" />

     </rdfs:seeAlso>
    </foaf:Document>
   </foaf:weblog>

<!-- a second weblog, detailing exclusively work activity -->
   <foaf:weblog>
    <foaf:Document rdf:about="http://foo.com/worklog/">
     <dc:title>Joe Bloggs' Work Journal</dc:title>
     <rdfs:seeAlso>
      <rss:channel rdf:about="http://foo.com/workblog/blog.rdf" />
     </rdfs:seeAlso>
    </foaf:Document>
   </foaf:weblog>
 </foaf:Person>
</foaf:member>

清单 2 中用粗体表示了所扩展的特性。实际上,用来处理清单 1 中那种格式的软件,应该会处理第2个 weblog 条目。针对清单 1 中格式的 RDF-aware 软件只是忽略特殊的主页和图象工具。此外,如果对元素的基数和次序不做任何设定,软件是不会有任何可行的 RDF 方法的。所以,一般要用 XPath 表达式来寻找您所需要的数据。

用 Redland RDF toolkit(请参阅 参考资料)可以很容易地处理 blog 清单。清单 3 列出了 bloginfo.py (在 参考资料 中可以链接到它的代码)中 FOAF 类的两个方法。

清单 3. bloginfo.py 中实现从 FOAF blog 清单提取信息的代码

from __future__ import generators
from RDF import *

class FOAF:
    def __init__(self,url):
        self.model = Model()
        Parser().parse_into_model(self.model,url)
        self.NAME = Node(uri_string="http://xmlns.com/foaf/0.1/name")
        self.NICK = Node(uri_string="http://xmlns.com/foaf/0.1/nick")
        self.TITLE = Node(uri_string="http://purl.org/dc/elements/1.1/title")

    def blogs(self):
        statement = Statement(subject=None,
                predicate=Node(uri_string="http://xmlns.com/foaf/0.1/weblog"),
                object=None)

        for i in self.model.find_statements(statement):
            yield i.object

构造函数 __init__ 通过参数传递获得 blog 清单的 URL,并把它解析成 RDF 模式。调用 blogs() 方法就可以很容易地找到清单中列出的所有 weblog,这个方法的谓词是查询所有 foaf:weblog 声明的对象。

RSS 解析器
Web 中使用的 RSS 解析器种类很多,从像我在文章“追溯 RDF 数据的源头”中提到的 RDF parser 这样非常精确的解析器,到非常自由的类型(不论得到的结果怎样,RSS 解析的狂热份子认为“自由”就是“实用”)。在这些自由的解析器中,我们选择 Mark Pilgrim 的 Feed Parser,目标编程语言选择 Python。(如果您想获得更多有用的资料,请参阅 参考资料 中的相关信息)从清单 4 中可以看到,它的使用方法是相当简单的。

清单 4. 用 Mark Pilgrim 的 RSS 解析器处理 RSS 提要

import rssparser

# etag and modified are set to the values we found when
# we last polled this RSS feed
data = rssparser.parse (rss, etag=etag, modified=modified,
       agent='Planet RDF Aggregator 0.1; http://planet.rdfhack.com/')

for item in data['items']:
    print item['title']

清单 4 中 parse() 调用的结果是一个 Python 词典。所有的 RSS 条目都存放在一个数组中,关键字是“items”字段的字符串。清单 4 的最后两行代码迭代了所有条目,并打印出它们的标题。

聚集
Planet RDF 聚集部分的代码相对比较简单,依次注册清单中的每一个 RSS 提要,获取每个 RSS 条目的键值,并保存所有条目的变化。获取每个条目的键值有点麻烦,但是这样做都是为了能同时使用 RSS 文件的 URL 和条目的 URL。使用这种方法,提要的提供者对条目的标题或描述做的任何改动都会被反馈。但是很不幸,如果 URL 中有一个错误,则会被聚集器认为是一个新的条目,而且这个错误条目不会被发现。避免这种情况的策略之一,是让生产者给每个 RSS 条目分配一个固定的标识符,但是现在看来这种方法显然还没有被广泛接受。

您可以通过阅读代码发现聚集的执行过程(请参阅 参考资料)是怎样的。但是与 XML 头部相比,更有意义的是最终的 Web 主页是怎么创建的。聚集器的输出实际上是它通过 RSS.py (由 Mark Nottingham 编写)创建的一个 RSS 文件。这个 RSS 文件包含了参与者 weblog 中所有最近一段时间的条目,按照从新到旧的时间顺序排列。为了提供 HMTL 输出,它采用了 XSLT 的风格。这样做的好处是可以得到一个现成的 RSS 文件,那样聚集的 weblog 就可以被加到用户的个人 RSS 阅读器中了。

运行软件
如果您想深究,可以通过 参考资料 中的链接下载软件并自己尝试一下。您需要安装 Python 2.2 以上版本和 Redland RDF 框架(请参阅 参考资料)。下载源文件,然后创建一个类似清单 1 那样的 bloggers.rdf 文件。您可以测试一下您的文件:修改 bloginfo.py 的 __main__ 部分,使它指向您的 RDF 文件,然后执行 python bloginfo.py

您必须修改主聚集器 chumpologica.py,在脚本的开始处设置您所使用的输出目录和数据目录。然后只要执行 python chumpologica.py bloggers.rdf 就可以了。聚集器会在您指定的目录中存放并且运行一个 RDF 文件:这是一个 RSS 1.0 文件。您可以用 XSLT 改进它。

结束语
Planet GNOME 聚集器很好地证明了,当包括了所有 weblog 的入口时,它的输出就会非常具有吸引力。按照惯例,这通过在 RSS 中把描述字段中的 HTML 实体转义成主体来完成。Norm Walsh 解释过这为什么是一件坏事(请参阅 参考资料)。RSS 1.0 有一种稍微好一点的机制对付它,称为 ccontent:encoded(请参阅 参考资料)。Planet RDF 代码在一些可以使用的地方接受 content:encoded,并通过删除 转义的 HTML 来清理滥用的 rss:description 属性;这个 HTML 实际上移入了聚集 RSS 1.0 文件中的 content:encoded 属性。 绝大多数情况下,这个 HTML 通过使用优秀的 HTML Tidy 工具(请参阅 参考资料)来修复,生成最终的符合 XHTML 1.0 规范的输出。

在处理不是直接面向个人工作的 weblog 时,还有一些问题没有解决。比如:

  • 组织或者临时组成员创建的提要
  • 无人代理创建的提要,比如 bug 跟踪系统

由于 Planet 风格的聚集器数量的不断增长(我写这篇文章的时候,Planets Apache 和 SuSE 正在紧张开发中),创建聚集网站的各种软件也增长起来。现在最少有 3 个代码库可以用来创建这样的网站,分别源自 Monologue、Planet GNOME 和 Planet RDF。如果这 3 个代码库能够合并会是一件很好的事情,哪怕是在有配置文件的基础上,就像清单 1 中的 RDF blog 清单。另外,我们想要一个更先进的方法来描述每个 planet,或许可以做一个 ber 聚集器 —— Planetarium!(实际上创建 Planet GNOME 的 Jeff Waugh 已经注册了域名“planetplanet.org”,可以去那里看看)。

我在 清单 5 中留给大家的代码,提到了怎样描述多个 planet:处理程序可以根据seeAlso 链接中找回每个 planet 的成员清单。如果选择使用 RDF/XML,创建 ber 配置文件和聚集各种 RDF blog 清单一样容易。

参考资料

  • 请阅读哈佛大学法学院的 weblog 主页,其中包括了 Donna Wentworth's definition of weblogs —— 网站“不断地被链接、评论和其他任何您喜欢的事物所更新。新条目不断被加到页首而老的条目很快会沉到页尾。”

  • 了解更多关于个人聚集器的信息,它已经被证明是最受欢迎的阅读 weblog 的方式。具体的例子包括 Mac OS X 的 NetNewsWire、Windows .NET 的 SharpReader 和 Unix GNOME desktops 的 Straw

  • 聚集开放源代码开发活动的网站包括 MonologuePlanet GNOME 以及 Planet Debian

  • 探讨 Outline Processor Markup Language (OPML),一种层次化文档概要格式,增加了对 RSS 提要清单的支持。

  • 对构建 Planet RDF 站点的团队的描述是:Matt Biddulph 负责聚集器编码;Dave Beckett 维护 RDF blogger 列表,并创建了 Redland RDF 框架,而 Phil McCarthy 进行设计。

  • 请阅读 Dave Beckett 的“Semantic Weblogs”清单,它可以用 XSLT stylesheet 方法从 XHTML 格式进入 RDF 格式,用来作为聚集器的源代码。

  • 很多的软件开发人员在使用 Advogato blogging工具,这是一个日志系统。

  • 进一步了解 Friend-of-a-Friend (FOAF),这是试图创建一个可供机器阅读的 web 主页的词汇表,这些主页描述人、人们之间的链接以及他们创建的和正在做的东西。 请参阅 Edd Dumbill 在 developerWorks 中的早期的专栏“使用 XML 和 RDF 找到朋友”(2002 年 6 月)和“使用 FOAF 支持在线社区” (2002 年 8 月)。

  • Mark Pilgrim 的 Feed Parser 用来解析比较自由的 RSS 语法,Mark Nottingham 的 RSS.py 是一个很好的关于 RSS 提要的连载课程。

  • 请阅读“Sticking with it -- RDF”,这篇文章阐述了用 RDF 表示 XML 词汇表的优点。

  • 下载 Redland RDF toolkit,它包括用来处理 RDF 的很好使的 Python 模块(在Planet RDF的结构中被使用)。developerWorks 中的文章“追溯 RDF 数据的源头”(2003 年 7 月)中已提及 Redland toolkit。

  • Planet RDF 的源代码是以 Matt Biddulph 的 Web 站点 中的“chumpologica”而闻名。

  • RSS 1.0 内容模块 指定一个 content:encoded 标签,用来避免 RSS 中 description 标签的有害的超载现象。

  • 在 Norm Walsh 于 XML.com 上发表的文章“Escaped Markup Considered Harmful”中,可以了解为什么通过转义一些特殊字符的方法使 XML 支持 HTML,这是一种不好的想法。

  • 我们花大量时间来检查我们所接受到的 HTML,为什么不检查一下我们输出的 (X)HTML 呢? HTML Tidy 是一个用来完成这项任务的极好工具。想要把花更多的时间在你所接受到的HTML标记上,而不在你写的(X)HTML标记上纠缠吗?

  • 阅读 James Lewin 的文章“RSS 2.0 内容提要”,可以更好地理解这个重要的格式。(developerWorks,2003 年 12 月)。

  • developerWorksXML 专区 中可以找到更多的 XML 参考资料,阅读以前各期的 XML 观察 专栏系列文章。

  • 请浏览 Developer Bookstore 中大量的打折 XML 图书。

  • IBM 的 DB2 数据库不仅支持关系数据库存储,也提供与 XML 有关的工具,比如可作为 XML 与关系系统之间桥梁的 DB2 XML Extender 。要学习有关 DB2 的更多知识,请访问 DB2 开发者园地

  • 了解如何才能成为一名 IBM 认证的 XML 及相关技术的开发人员

关于作者
Edd Dumbill 是
XML.com 的执行编辑和 XML 开发人员新闻站点 XMLhack 的编辑和发行人。他是 O'Reilly's Programming Web Services with XML-RPC 一书的合著者,以及 Pharmalicensing 生命科学知识产权交易事务所的共同创始人和顾问。Edd 还是 XML Europe 大会的议程主席。可以通过 edd@xml.com 与 Edd 联系。



到页首
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值