介绍AxKit

系列介绍

本文是该系列文章的第一篇,介绍了AxKit Web应用平台。从基础知识开始,本系列将解释如何安装基本的AxKit服务器,然后探讨AxKit更强大的功能。假设您对(或能够通过Google搜索)XMLApachemod_perl有一定了解,但不需要专业知识。本文末尾提供了一些参考和有用资源,以帮助您入门。

AxKit:它是做什么的?

如果您已经了解AxKit和服务器端XML处理的奇妙之处,您可能希望跳到基本安装部分。

AxKit是一个应用程序和文档服务器,它使用XML处理管道生成和处理内容,并以多种格式将其交付给客户端。需要注意的是,AxKit不仅限于XML源文档;非XML文档和数据源可以根据需要转换为XML。一个基本的AxKit管道看起来像这样

Axkit Processing Overview

源文档可能是一篇文章、数据集、数据库查询返回的数据、Perl例程的输出、mod_perl处理器、CGI脚本等。此文档被送入第一个处理器(“变换1”),根据“样式表”对其进行更改,该样式表指定了对文档应用的一系列变换。第一个处理器的输出被送入第二个处理器,第二个处理器送入第三个处理器,依此类推,直到最终文档被传递到浏览器。

AxKit提供了传统XML处理技术(如XSLT)、适合动态内容的高级处理(如Perl版本的XSP和标签库)以及Perl的低级处理,后者适用于高级抽象只会阻碍的情况。

AxKit提供了无缝缓存(生成动态内容的代码和变换文档的代码)、压缩和字符集转换。AxKit还允许使用其他技术(CGI脚本、会话管理工具、数据转换器、Perl模块、Inline::C等)来扩展其功能。

当前版本(v1.5)与Apache/mod_perl紧密耦合,并利用该平台的出色可配置性和性能;正在进行工作,以使其能够在其他环境(如离线处理、cgi-bin和独立服务器)中使用。

为什么选择AxKit?

围绕浏览器端XML处理的炒作让人感觉似乎几乎没有或没有服务器端XML处理的必要。然而,出于各种原因,浏览器中的XML并非到处都有,而且在可用的情况下,也有服务器端处理可以解决的限制。

服务器端XML处理允许在将“最终”HTML、XML、文本、SVG或其他输出发送到浏览器之前查询、重新组织、翻译、样式化等内容。服务器可以使用最有效和最合适的技术(与客户端可用的相对有限工具相比,即使您可以控制客户端配置)实施重型数据处理。然后,服务器可以决定交付一个格式化的文档,用于展示和显示,或将展示格式化(及其相关的处理开销)委托给客户端。在某种程度上,这是一个理想的方法:使用服务器应用重型或非同寻常的变换,并将展示格式化委托给浏览器。

使用服务器端XML的一些优点包括

  • XML可以在服务器上转换为多种内容传输语言:XML、WML、XHTML、HTML、RTF、PDF、图形格式、纯文本等。
  • 演示可以与内容和技术分离,这样转换演示并不意味着修改XML文档或作者工具上的设置。本文将演示如何分离逻辑、内容和演示。
  • 即使是使用相同的内容传输语言(例如HTML),文档也可以以不同的方式格式化,以适应不同的显示媒体,例如屏幕与打印机。
  • XML支持指定字符编码。源文档可以转换为不同的字符集,具体取决于浏览器。
  • XML文档可以按其“主要”显示模式以自然顺序表达,并重新排序以提供不同的数据视图。例如,文档词汇表或索引中的术语不是按文档顺序排列的。
  • 随着网站的内容和能力的发展,可以在新内容中引入新的XML标签,而无需“升级”旧文章。本文将简要介绍标签库(taglibs),并在后续文章中对其进行更深入的探讨。
  • XML相关技术变得越来越为人所知;招聘具有XML知识的人员变得更加容易。对于内部专有格式,您始终需要自己培训他们。对于第三方专有格式,您希望获得足够的培训来完成所需的工作。
  • XML处理工具(XSLT、编辑器等)变得越来越普遍,因此将XML应用于IT部门之外是可行的。尽管一些WYSIWYG作者工具现在商业上可用,但对其支持仍存在差距。
  • 对于提供足够功能的浏览器,XML可以选择在客户端进行转换,从而减少服务器负载。对于较大的页面,请准备好客户端转换可能较慢,您可能需要在服务器上执行重新排序和子集操作。
  • XML可以以多种格式提供对您的网站结构和内容的描述。“语义网”即将来到您的浏览器(真的很快就到了 ;-)。关于网络的最大学术担忧之一是缺乏语义内容。当查看HTML格式的图书页面时,谁又能说用<H1>包围的标题是书的作者、标题、出版社,甚至是一个章节或部分标题呢?XML可以用来阐明这些问题,而像资源描述框架(RDF)这样的标准正在这个领域取得进展。
  • 基于XML的技术,如RDF Site Summary(RSS)和更通用的资源描述框架,可以用来允许其他网站自动导航、聚合和总结网站内容。这对于包含最新新闻和新闻稿的网站部分尤其适用;这些通常在其他网站的新闻摘要和“头条”页面上复制。

AxKit能够实现所有这些以及更多。与一些较为封闭的环境不同,AxKit可以轻松地与其他任何可以加载到Apache web服务器或通过外部请求访问的技术结合。

基本安装

本节将指导您进行手动安装,但如果您只是想试用AxKit,有一个更简单的方法:获取本文的AxKit演示tar包,解包并运行其中的install脚本。该tar包包含大多数现代Unix-like系统所需的所有先决条件,并且将随着每篇文章更新新版本和示例代码。如果这对您有效(已在Linux和FreeBSD上进行了测试),您可以跳过所有手动安装说明,并跳转到测试AxKit

AxKit结合了许多不同的技术,并使用了许多CPAN模块。如果CPAN.pm(或等效;截至本文撰写时,CPANPLUS正在开发中)在您的系统上运行,则进行基本手动安装并不困难。

安装AxKit的第一步很大,但通常并不困难:安装Apache和mod_perl 1.x版本(2.x版本正在开发中,但截至本文撰写时尚未发布)。《mod_perl开发者指南》详细介绍了这个过程。以下是Unix系统在/home/me/axkit_articles-1.0(根据需要更改版本号)上进行“私有”安装(即非root)的快速方法。

$ mkdir axkit_articles-1.0
$ cd axkit_articles-1.0
$ lynx https://httpd.apache.ac.cn/dist/httpd/  # Get the latest 1.x version of apache
$ lynx https://www.apache.org/dyn/closer.cgi/perl/mod_perl-1.31.tar.gz  # Get the latest 1.x version of mod_perl.
$ gunzip apache_1.3.23.tar.gz
$ tar xf apache_1.3.23.tar
$ gunzip mod_perl-1.26.tar.gz
$ tar xf mod_perl-1.26.tar
$ cd mod_perl-1.26
$ perl Makefile.PL \
>   APACHE_SRC=../apache_1.3.23/src/ \
>   DO_HTTPD=1 \
>   USE_APACI=1 \
>   APACHE_PREFIX=/home/me/axkit_articles-1.0/www \
>   PREFIX=/home/me/axkit_articles-1.0/www \
>   EVERYTHING=1
$ make
$ make test
$ make install

通常明智的做法是将AxKit/mod_perl/Apache构建过程写入脚本中,这样您可以对其进行调试、重复和按需修改。这样的服务器功能强大且可配置;您很可能希望为它们创建一个可重复、可调整的构建环境。

在Windows上,在https://httpd.apache.ac.cn/dist/binaries/win32/中查找最新的Apache Win32二进制文件,然后使用PPM安装mod_perl二进制文件注意:不建议在生产Apache/mod_perl服务器上使用Windows;Apache/mod_perl 1.x在这个平台上扩展性不佳;Apache/mod_perl 2.x正在解决导致此问题的基本架构分歧。

如果一切顺利,运行

$ www/bin/apachectl start

应在8080端口启动一个(非AxKit)httpd。如果出现问题(这两个包都很成熟,所以问题不常见),请参阅文章末尾的参考和有用的资源部分,以获取一些寻求帮助的地方。

下一步是安装一些AxKit的先决条件:GNOME项目的libxml2和libxslt将被本系列文章中的示例使用,尽管该项目使用libxml2。要检查它们是否已安装,请尝试

$ xml2-config --version
2.4.13                         # Need >= 2.4.13
$ xslt-config --version
1.0.10                         # Need >= 1.0.10

如果没有,从文章的源tarball或任意GNOME镜像获取它们,并使用./configure && make && make install安装它们。上面的tarball将所有先决条件安装在“私有”安装树中;这里我们在系统的共享位置安装它们,以保持手动安装简单。如果您想要私有副本,请查看安装脚本生成的命令。

请注意:libxslt 1.0.10在其测试套件中有一个已知的(非常小的)失败,这导致在测试tests/exslt/sets/has-same-node.1.xsl时在某些系统上make失败。本文源tarball提供的install脚本在运行make之前会删除这个有问题的测试。

现在,所有主要先决条件都已安装,让我们让CPAN.pm安装最后的部分

$ su
Password:
# perl -MCPAN -e shell
...
cpan> install XML::LibXSLT
...
cpan> install AxKit::XSP::Util
...
cpan> quit
# exit

AxKit::XSP::Util的安装应安装AxKit和其他一些先决条件。如果CPAN.pm对您不起作用,您可能只想下载上面提到的axkit-demo tarball,并手动安装您在那里找到的包。但是,这些包很多,所以让CPAN工作可能是手动安装的最简单方法。

测试AxKit

从现在开始,所有提到的相对目录都假设您在axkit_articles-x.y目录中,除非另有说明。

一旦所有必需的模块都已安装,请调整www/conf/httpd.conf文件以通过添加

##
## AxKit Configuration
##

PerlModule AxKit

<Directory "/home/me/axkit_articles-1.0/www/htdocs">
    Options -All +Indexes +FollowSymLinks

    # Tell mod_dir to translate / to /index.xml or /index.xsp
    DirectoryIndex index.xsp
    AddHandler axkit .xml .xsp

    AxDebugLevel 10

    AxGzipOutput On

    AxAddXSPTaglib AxKit::XSP::Util

    AxAddStyleMap application/x-xsp \
                  Apache::AxKit::Language::XSP
</Directory>

我们将稍后介绍配置,但首先让我们添加一个看起来像的www/htdocs/index.xsp测试页面

<?xml-stylesheet href="NULL" type="application/x-xsp"?>
<xsp:page
    xmlns:xsp="http://www.apache.org/1999/XSP/Core"
    xmlns:util="http://apache.org/xsp/util/v1"
>
  <html>
    <body>
      <p>Hi! It's <util:time format="%H:%M:%S"/>.</p>
    </body>
  </html>
</xsp:page>

现在您应该能够重新启动服务器并像这样请求测试页面(添加了空白以便于阅读,并且可以与index.xsp进行比较)

$ www/bin/apachectl restart
$ lynx -source http://127.0.0.1:8080/
<?xml version="1.0" encoding="UTF-8"?>
<html>
  <body>
    <p>Hi! It's Tue Feb  5 16:26:31 2002.</p>
  </body>
<html>

每个请求都应该生成一个带有不同时间戳的新页面。如果您发现端口8080上已经运行了某些东西,您可能需要调整www/conf/httpd.conf中的Port指令。

示例的工作原理

本系列中的后续文章将更深入地探讨AxKit的各种功能,现在让我们看看安装部分中的示例是如何工作的。

实际上,希望在下篇文章中,AxKit的新版本将提供一个简单的演示功能,展示其主要XML处理选项。如果这样的话,下篇文章附带的压缩包将包含这个新版本。

配置

AxKit与Apache配置引擎紧密集成。Apache配置引擎远不止一个文本文件解析器:它是Apache请求处理能力的基础,也是Apache灵活性和扩展性的关键。上面添加到服务器配置中的指令是原生Apache指令和AxKit指令的混合。让我们看一下请求周期的第一部分,看看Apache配置指令如何影响请求。

Apache httpd主要是一个配置引擎和一组专用模块的集合。这次讨论忽略了除mod_perl和AxKit之外还使用了几个模块来处理这个请求的事实,并将它们统称为“Apache”。

当HTTP请求到达时,Apache解析它,并将URL路径部分(“/”)映射到硬盘上的一个位置(/home/me/axkit_articles-1.0/www/htdocs)。URI映射到一个目录,Apache指令“DocumentRoot”(未显示,它是默认安装的一部分),“<Directory>”,“Options +Indexes”和“DirectoryIndex”导致Apache将这个URI映射到文件index.xsp

现在已经确定了底层资源,Apache使用.xsp扩展名来确定应该使用哪个模块将资源传送给浏览器。指令AddHandler AxKit .xsp告诉Apache将响应处理委托给AxKit。这与为URI建立mod_perl处理器非常相似,只不过它是用C实现的,比标准的mod_perl响应处理器要快一些。

处理链

测试文档index.xsp是XSP(可扩展服务器页面)的一个例子,这是AxKit支持的语言之一。我们稍后会介绍如何处理XSP。

当AxKit开始处理响应的任务时,它已经通过与合作Apache配置引擎处理了它的配置指令。这些指令有以下效果

AxDebugLevel 10www/logs/error_log中产生大量输出。

AxGzipOutput On 启用自动gzip压缩(通过Compress::Zlib)。这仅在客户端可以接受压缩文档的情况下使用。AxKit甚至更进一步,为一些可以处理它但未正确设置HTTP Accept-Encoding:头部的客户端压缩输出。

AxAddStyleMap application/x-xsp Apache::AxKit::Language::XSP 建立了MIME类型“application/x-xsp”与Apache::AxKit::Language::XSP模块之间的映射。我们很快就会看到这种映射是如何告诉AxKit在应用转换类型时使用哪个模块的。

AxAddXSPTaglib 标记XSP引擎需要加载AxKit::XSP::Util(这提供了一些由index.xsp调用的Perl代码)。

AxKit在处理响应时需要做的第一件事是配置处理管道。AxKit首先寻找指示的地方是源文档;它扫描源文档中的<?xml-stylesheet...?>处理指令,如

<?xml-stylesheet href="NULL" type="application/x-xsp"?>

AxKit有两种替代机制,提供了更多功能和灵活性;我们将在后续文章中更深入地探讨这些内容。

xml-stylesheet PI 指定应用于源文档的变换列表;这些变换按在文档中出现的顺序应用。每个处理指令指定一个样式表(在这种情况下是“NULL”:XSP 不使用它们,我们稍后将其介绍),以及处理器类型(“application/x-xsp”)。AxAddStyleMap 指令指定哪些 Perl 模块处理处理器类型,并且在我们的示例中,将 application/x-xsp 映射到 Apache::AxKit::Language::XSP。

这相当复杂;下面是一个图表,展示了这个示例中最重要部分如何影响处理流程

index.xsp configuration data flow

并且结果流程看起来像这样

index.xsp processing pipeline

如图所示,源 .xsp 页面从磁盘读取,然后编译成 Perl 源代码(根据需要使用 util: 标签库),并在磁盘上缓存。然后运行生成的源代码以生成此请求的结果文档,该文档如果客户端支持压缩,则进行压缩,并发送到客户端。

AxDebugLevel 设置为至少 10 时,您可以在 www/logs/error_log 中查看源代码。

请注意,AxKit 足够智能,不会缓存输出文档(XSP 处理器和输出之间没有缓存);XSP 旨在用于动态页面,其输出文档不应被缓存。

index.xsp 编译时,生成的代码将输出文档节点逐个构建。<util:time .../> 标签被转换为调用 perl 的 localtime 函数的子程序调用。请参阅 error_log(我们的 AxDebugLevel 设置为 10,因此 XSP.pm 将此输出到错误日志),并查看 AxKit::XSP::Util 中的 get_date() 函数以了解 localtime() 调用。

XSP 和 Taglibs

XSP 与大多数 XML 处理“语言”不同,它实际上不使用样式表;相反,XSP 页面包含特殊标签,每次请求页面时都会执行这些标签。例如,在 index.xsp 中,<util:time format="%H:%M:%S"/> 标签被转换为调用 localtime 的 Perl 代码。

大多数 XML 过滤器将变换应用于源 XML 以生成结果 XML。这些变换被称为“样式表”。如前所述,XSP 不使用样式表。我们将在未来的文章中介绍基于样式表的变换。

标签的 util: 部分是一个前缀,表示 util 标签库将处理该标签。util: 前缀是一个 XML 命名空间 前缀,不是硬编码的;index.xsp 的根元素中的 xmlns:util 属性将 util: 前缀绑定到标签库。

<xsp:page
    xmlns:xsp="http://www.apache.org/1999/XSP/Core"
    xmlns:util="http://apache.org/xsp/util/v1"
>

提供 util: 标签库背后代码的模块 AxKit::XSP::Util 在其中硬编码了相同的 URI(”http://apache.org/xsp/util/v1”)。当在 httpd.conf 文件中看到 AxAddXSPTaglib 指令时,AxKit::XSP::Util 会向 XSP 模块注册以处理该命名空间中的所有标签。

一个 XSP 页面可以包括所需的任何标签库命名空间和标签。CPAN 包含一个 庞大且不断增长的标签库集合,用于 AxKit 的 XSP 实现,我们将在下一两篇文章中探讨为 Apache 编写标签库的两种方法。

标签库方法表面上类似于 CPAN 上的许多模板引擎;实际上,一些模板系统最近已经扩展以包括标签库。然而,这些与 XSP 之间有几个重要区别。

  • XSP 输入文件必须是良好形成的 XML,这使得无法生成格式错误的 XML。在使用模板系统时,内容标记中的拼写错误可以轻易地到达浏览器而没有任何警告。
  • 在将其交给 XSP 处理器之前,源文档可能已进行变换。这允许您构建作为 XSLT 变换的简单标签库,这些变换部署在 XSP 处理器上游。因为 AxKit 的 XSP 将 XSP 页面转换为代码并缓存代码,所以这些变换不会在每个请求中运行;它们被捕获在缓存的代码中。这也可以用来“捕获”静态变换。
  • XSP鼓励将内容、逻辑和表现分离;XSP页面向内容添加逻辑,并生成格式良好的XML,这些XML可以被“真正的”样式表润色,以实现不同的展示。
  • 与一些更复杂的模板系统一样,XSP设计为可扩展;添加标签库就像在httpd.conf文件中配置添加AxAddXSPTaglib语句,然后在源文档中引用它一样简单。在测试代码中,<util:time>标签由Apache::XSP::Util模块提供,并且您可以将所需的标签库加载到服务器中。

里程碑1和未来的道路

这是本系列的第一篇文章,介绍了AxKit的安装,并介绍了AxKit的一种处理技术:XSP。在下一篇文章中,我们将看到如何链接过滤器以将样式表应用于静态文档和XSP生成的文档,以便以不同的形式交付相同的文档。之后,我们将探讨如何使用一些辅助模块和XSLT在Perl中编写标签库(推荐的方法)。

参考和有帮助的资源

有几个非常有帮助的地方可以进行问题研究、提问和学习。当然,在提问之前,尽量找到其他人之前遇到过类似问题,但这里列出的用户组是提问的地方

AxKit网站(您阅读此内容时可能已迁移到xml.apache.org网站)这是“官方”的AxKit网站。

AxKit指南对AxKit的深入介绍。

[email protected]邮件列表。浏览存档订阅。这是讨论AxKit特定问题并提出解决方案、补丁和成功故事的地方。这里列出的mod_perl资源对于一般的mod_perl构建和支持问题也非常合适。

mod_perl开发者指南检查Apache+mod_perl构建建议和调试技巧的首选地方。

[email protected]电子邮件存档查看是否有人遇到过您的问题并且(通常)找到了解决方案。此列表在撰写本文时即将迁移到@perl.org地址,因此我不会指向即将过时的订阅表单。

[email protected]一个针对通用perl和XML问题的邮件列表,包括axkit支持。(在http://listserv.activestate.com/mailman/listinfo/perl-xml上订阅)。

irc.rhizomatic.net上的#axkitIRC频道。这是一个友好的地方,您通常可以从经验丰富的AxKit用户和贡献者那里快速获得建议。

与所有在线开源社区一样,请尽量将您收到的任何帮助传递下去。

感谢Martin Oldfield、Kip Hampton和Robin Berjon对技术审查的彻底性,尽管我确信我设法绕过了他们的一些漏洞。AxKit和它使用的许多Perl模块主要是由Matt Sergeant编写的,这些好人以及其他人的贡献非常广泛,所以也要感谢所有贡献者。

版权2002,Robert Barrie Slaymaker,Jr。版权所有。

标签

反馈

这篇文章有问题吗?请通过在GitHub上打开一个问题或拉取请求来帮助我们。