當(dāng)前位置:工程項(xiàng)目OA系統(tǒng) > 泛普各地 > 河南OA系統(tǒng) > 鄭州OA系統(tǒng) > 鄭州OA信息化
使用XML:將XSLT用于內(nèi)容管理
使用XML:將XSLT用于內(nèi)容管理
--介紹XM,窮人的內(nèi)容管理器
Beno顃 Marchal (bmarchal@pineapplesoft.com)
顧問,Pineapplesoft
2001 年 7 月
這是使用 XML 專欄的第一部分,該專欄帶有相應(yīng)項(xiàng)目代碼,演示了成熟 XML 應(yīng)用程序的演變。在這一專欄中,作者兼軟件顧問
Beno顃 Marchal 介紹了 XM(XSLT Make),一種利用 XML 和 XSLT 的簡單的、負(fù)擔(dān)得起的 Web
發(fā)布內(nèi)容管理解決方案。代碼樣本顯示了 XSLT 封裝器的開發(fā),使得非程序員也能輕松使用??梢酝ㄟ^鏈接獲得 XM 項(xiàng)目代碼。
歡迎來到使用 XML
專欄 — developerWorks 上的一個(gè)新專欄 — 的第一部分。該專欄的前提是,開發(fā)人員最好通過研究代碼來學(xué)習(xí),因此我會隨同專欄一起開發(fā)一系列 XML
項(xiàng)目,這些項(xiàng)目將在幾篇專欄文章中討論。感謝這種形式,這樣我可以解決更大、更現(xiàn)實(shí)的項(xiàng)目,而不是通??赡軆H為一篇文章的情景所構(gòu)思的項(xiàng)目。請注意,您可以在本專欄伙伴站點(diǎn)上找到作為開放源碼項(xiàng)目的演示項(xiàng)目本身(請參閱參考資料)。我期待著這些項(xiàng)目可以隨著你我的使用而不斷發(fā)展,屆時(shí)我會在這里報(bào)告那些更改。
這一形式另一有趣的特性是您可以一直跟蹤項(xiàng)目,從初期到完成。我發(fā)現(xiàn),人從錯(cuò)誤中學(xué)到的如果說不比從有效的解決方案中更多的話,那至少也是差不多的。因?yàn)槭褂? XML 跟蹤的是實(shí)際項(xiàng)目的開發(fā),所以比起在只有一種假設(shè)情況的一篇一次性文章中,我有更多機(jī)會告誡您提防死胡同。我希望將正在進(jìn)行的開放源碼項(xiàng)目和專欄結(jié)合可以讓我們成為更好的開發(fā)人員。
XM:窮人的內(nèi)容管理器
我要完成的第一個(gè)項(xiàng)目是一個(gè)負(fù)擔(dān)得起的 Web
發(fā)布解決方案。管理一個(gè)超過 200
個(gè)頁面的網(wǎng)站的艱難經(jīng)歷是這個(gè)項(xiàng)目的靈感來源。我發(fā)現(xiàn)有一些非常好的工具可以用來管理或小或大的站點(diǎn),但我無法找到介于兩者之間的適當(dāng)解決方案。
如果您的站點(diǎn)有 10 到 20 個(gè)頁面,那么象 HoTMetaL PRO、DreamOA 或 FrontPage(請參閱參考資料)這樣的 HTML 編輯器非常不錯(cuò)。不過,隨著站點(diǎn)不斷成長,以及工作從創(chuàng)建轉(zhuǎn)移到相對昂貴的維護(hù)上,這些工具就證明不那么有效了。許多 HTML 編輯器都不是很適合于維護(hù)不斷增長的站點(diǎn)。例如,它們可能會強(qiáng)迫您手工編輯所有頁面而只是為了重新設(shè)計(jì)一下導(dǎo)航-如果管理數(shù)量在二十幾個(gè)以下的頁面,這樣做只是麻煩一些,但對于數(shù)量更多的站點(diǎn),就要做太多工作了。
領(lǐng)域的另一端是高端發(fā)布解決方案,例如 OpenMarket、Vignette 或 eContent(請參閱參考資料)。它們在管理具有巨大內(nèi)容庫的大型站點(diǎn)方面做得很好,但(總是有“但”)門票很貴,貴得令大多數(shù)超負(fù)荷的網(wǎng)站管理員可能只能夢想擁有這樣的一個(gè)系統(tǒng)。
那么這中間是什么呢?自己開發(fā)的解決方案。許多網(wǎng)站管理員都已轉(zhuǎn)向腳本(JSP、ASP 或 PHP)和數(shù)據(jù)庫的組合以幫助他們應(yīng)付不斷成長的站點(diǎn)。這種方法很有效,但不是沒有缺點(diǎn)。首先,增加了服務(wù)器代價(jià),因此頁面可能裝入得更慢。另外,基于腳本的網(wǎng)站更容易出現(xiàn)錯(cuò)誤,甚至崩潰(當(dāng)然,我是在說自己;錯(cuò)誤不會困擾 您的代碼)。最后,搜索引擎往往不太可能對動(dòng)態(tài)生成的站點(diǎn)建立索引??偟膩碚f,我發(fā)現(xiàn)雖然腳本和數(shù)據(jù)庫可以使網(wǎng)站管理員的生活更輕松,但對于訪問者來說,它們遠(yuǎn)遠(yuǎn)不夠理想。
為了適合有關(guān) XML 的專欄,我提出了在 XML 和 XSLT 上構(gòu)建的一種替代辦法。準(zhǔn)備 DocBook 或另其它 XML 詞匯格式的文檔,然后將它們自動(dòng)轉(zhuǎn)換成 HTML 確實(shí)很容易。自動(dòng)在這里是最重要的詞。目的是加快手工處理,并盡可能地將站點(diǎn)維護(hù)自動(dòng)化。當(dāng)從小規(guī)模轉(zhuǎn)移到工業(yè)規(guī)模的網(wǎng)站管理時(shí),我愿意考慮它。
至少,在理論上說是這樣。實(shí)際上,要在家里嘗試這些,您最好是程序員。象 Xalan 這樣的 XSLT 處理器使用起來確實(shí)還不是那么友好。存在象 Cocoon 這樣的 XML 發(fā)布框架(請參閱參考資料),但它們還是適合于開發(fā)人員的。我對 XM(XSLT Make)期待的目標(biāo)是讓 XSLT 處理器有張友好的面孔。最終,我希望那些管理中型網(wǎng)站的非開發(fā)人員也能使用 XM。
我選擇這個(gè)項(xiàng)目作為使用 XML 的第一個(gè)項(xiàng)目是因?yàn)?,從讀者對最近的一篇 developerWorks 文章 - Managing e-zines with JavaMail and XSLT -反饋的郵件看來,對用于發(fā)布的 XSLT 友好應(yīng)用程序感興趣的人不在少數(shù)。
線路圖
圖 1 概述了 XM
是如何工作的。準(zhǔn)備和發(fā)布網(wǎng)站有三個(gè)階段:
創(chuàng)作:使用 XML 編輯器編寫內(nèi)容,或者從非 XML 來源(例如字處理器)獲取
發(fā)布:將內(nèi)容轉(zhuǎn)換成 HTML
欣賞:在瀏覽器中查看內(nèi)容
圖 1:使用 XM 進(jìn)行 Web 發(fā)布的三個(gè)步驟
我要提醒您注意,XM 生成的大多是靜態(tài) HTML 頁面。目標(biāo)是幫助網(wǎng)站管理員更好管理網(wǎng)站
-不必犧牲原來的性能。要增強(qiáng)性能,大多數(shù)動(dòng)態(tài)生成的網(wǎng)站使用某種形式的高速緩存。我相信靜態(tài) HTML
頁面,到目前為止,是最好的高速緩存策略。
您可以發(fā)現(xiàn),這個(gè)項(xiàng)目相當(dāng)煩瑣,我并沒有計(jì)劃在一篇(甚至兩篇)專欄文章中實(shí)現(xiàn)其全部。和其它任何認(rèn)真的開發(fā)項(xiàng)目一樣, 使用 XML 的項(xiàng)目將在幾個(gè)月內(nèi)不斷成熟起來。但為了給這一部分做出結(jié)論,我仍然希望指出一些我已認(rèn)識到的難點(diǎn)和里程碑。很明顯,我期待著隨著開發(fā)進(jìn)行添加更多內(nèi)容:
為 XSLT 處理器設(shè)計(jì)一個(gè)易于使用的包裝(包括在本專欄中)。
自動(dòng)通過 FTP 將文件上載到 Web 服務(wù)器。
管理文件和那些文件之間的鏈接(一種解決方案可能是讓樣式表讀取目錄)。
支持例如 PDF(Adobe Acrobat
支持的“可移植文檔格式”)、SVG(用于圖像的“可伸縮向量圖形”)、RSS(用于 Web 門戶的“豐富站點(diǎn)摘要”)等多種發(fā)布格式。
在 Web
服務(wù)器本身上存放 XM 以支持協(xié)作編輯。
內(nèi)容管理例解
XM
第一版中的主要挑戰(zhàn)之一在于使它可用于非程序員。我不僅僅指帶有友好按鈕的漂亮用戶界面。我相信許多漂亮按鈕并不能使不友好的解決方案看起來友好;它仍然是不友好的應(yīng)用程序。當(dāng)然,我已嘗試設(shè)計(jì)一種易于理解的可操作方式。
我的第一個(gè)想法是在“Managing e-zines with JavaMail and XSLT”中的配置文件上進(jìn)行構(gòu)建。如果您沒看過那篇文章,我可以告訴您,配置文件控制著應(yīng)用哪些樣式表,以及結(jié)果應(yīng)該怎樣。有關(guān)示例,請參閱清單 1。我測試過許多變體,但無論我嘗試什么,都無法找出足夠友好的方案。
清單 1. rules.xml:創(chuàng)建友好的配置文件的許多嘗試之一
<?xml version="1.0"?>
<rules version="1.0"
xmlns="http://www.ananas.org/2001/xm/rules">
<!-- apply the style sheet on XML files
-->
<rule
extension="xml">
<apply-stylesheet
file="default.xsl"/>
<copy from="$xslt"
to="$target"/>
</rule>
<!-- copy GIF
files -->
<rule
extension="gif">
<copy from="$source"
to="$target"/>
</rule>
<!-- create
an XML file with the content of
freebies/download, style it -->
<rule
directory="freebies/download">
<ls
dir="$current"/>
<apply-stylesheet
file="download.xsl"/>
<copy from="$xslt"
to="$target"/>
</rule>
</rules>
然后它使我受到了打擊,這樣一個(gè)帶有規(guī)則和變量(例如 $source)的配置文件天生難以使用。它與腳本語言類似,我們都知道,腳本語言是不適合初學(xué)者的。我偶然發(fā)現(xiàn)了一個(gè)更容易使用的解決方案:讓用戶創(chuàng)建一個(gè)模擬最終網(wǎng)站的目錄,并自動(dòng)產(chǎn)生輸出。我將它稱為 內(nèi)容管理例解,這是因?yàn)橛脩魧?shí)際上創(chuàng)建了如何組織網(wǎng)站的示例,而且 XM 不需要更多配置就可以將它變成真正的網(wǎng)站。
骨架類
如果您計(jì)劃按照示例操作,請?jiān)煸L
ananas.org,然后下載項(xiàng)目代碼;在繼續(xù)閱讀下去之前需要它。我在本月介紹的代碼不過是 XM
的骨架。它只做最基本的事:遞歸地遍歷源目錄,在此過程中將樣式表應(yīng)用到每個(gè) XML 文件以產(chǎn)生 HTML 格式的網(wǎng)站。
到目前為止,這些類包括:
NotImplementedException 是 Java
標(biāo)準(zhǔn)庫中我一直非常懷念的唯一類。
在開發(fā)過程期間,嘗試調(diào)用還未實(shí)現(xiàn)的代碼或遇到意外(因此是未實(shí)現(xiàn)的)情況并不罕見。我發(fā)現(xiàn),明確說明我還沒有編寫代碼一直以來節(jié)省了我調(diào)試工作所花的大量時(shí)間。
XMException,當(dāng) XM 遇到錯(cuò)誤時(shí),它拋出這個(gè)異常。這個(gè)異??梢郧度肫渌惓?,例如 TransformerException 或
SAXException。
Resources 只是便利手段。它為我提供了對缺省語言環(huán)境中資源的快速訪問。
Messenger
是與抽象錯(cuò)誤和信息消息的接口。當(dāng)前版本的 XM 從命令行運(yùn)行,但我期望構(gòu)建的是 GUI 或基于 Web 的界面。通過將所有消息經(jīng)過 Messenger
傳輸,支持不同界面就容易了。
DefaultMessenger 是打印到 Writer 的 Messenger 缺省實(shí)現(xiàn)。
DirectoryWalker 執(zhí)行實(shí)際的處理。它遞歸地遍歷一組目錄,在這個(gè)過程中應(yīng)用樣式表。
Console 是 XM
的入口點(diǎn)。就象其名稱所揭示的,它是從命令行運(yùn)行的。
Messenger
如果您忘了異常,那么我告訴您,到目前為止 XM 中兩個(gè)最有用的類是
Messenger 和 DirectoryWalker。清單 2 中的 Messenger 定義了與用戶進(jìn)行通信的接口。這個(gè)類模仿了 TrAX 的
ErrorListener 或 SAX 的 ErrorHandler:
error()、fatal() 和 warning() 用于報(bào)告錯(cuò)誤。
progress()
可以用來實(shí)現(xiàn)進(jìn)度欄或另一種向用戶報(bào)告進(jìn)度的機(jī)制。
info() 報(bào)告其它信息。
因?yàn)?XM
主要是一個(gè)非交互式過程,所以我沒有定義任何提示用戶,或者另外接受輸入的方法。
清單 2. Messenger.java: XM 對用戶的接口
package org.ananas.xm;
import java.io.File;
public interface Messager
{
public void
error(XMException e)
throws
XMException;
public void fatal(XMException
e)
throws XMException;
public void warning(XMException
e)
throws XMException;
public void progress(File sourceFile,File
resultFile)
throws XMException;
public void info(String
msg)
throws XMException;
public void info(String pattern,Object[]
arguments)
throws XMException;
}
DirectoryWalker
清單 3 中的
DirectoryWalker 主要是將 XML 文件從源目錄(包括其子目錄中的文件)復(fù)制到目標(biāo)目錄。只有一個(gè)竅門:它在復(fù)制 XML
文件之前對它們應(yīng)用了一個(gè)樣式表。
清單 3. DirectoryWalker.java:有趣的所在
package org.ananas.xm;
import java.io.*;
import java.util.*;
import
javax.xml.transform.*;
import javax.xml.transform.stream.*;
import
org.ananas.util.NotImplementedException;
public class DirectoryWalker
{
protected
Templates templates;
protected long
lastModified;
protected String extension;
protected Messager messager = null;
public DirectoryWalker(File stylesheetFile,Messager
messager)
throws
TransformerConfigurationException
{
lastModified =
stylesheetFile.lastModified();
templates =
TransformerFactory.newInstance().
newTemplates(new
StreamSource(stylesheetFile));
extension = '.'
+
templates.getOutputProperties().
getProperty(OutputKeys.METHOD);
this.messager
= messager;
}
public void walk(String source,String
target)
throws IOException,
XMException
{
walk(new
File(source),new File(target));
}
protected void walk(File source,File
target)
throws IOException,
XMException
{
if(source.isDirectory())
{
File[] files =
source.listFiles(),
dirs = new
File[files.length],
docs = new
File[files.length];
int
idirs =
0,
idocs = 0;
for(int i = 0;i
< files.length;i++)
{
if(files[i].isDirectory())
dirs[idirs++] =
files[i];
else
if(files[i].isFile())
docs[idocs++] =
files[i];
else
throw new NotImplementedException("Expecting file or
directory");
}
if(!(target.exists()
&&
target.isDirectory()))
if(!target.mkdirs())
messager.fatal(new
XMException(
Resources.getString("cannotcreatedirectory"),
new Object[]
{target.getAbsolutePath()}));
for(int i = 0;i <
idocs;i++)
{
String
fname =
docs[i].getName();
int pos =
fname.lastIndexOf('.');
String extension = pos != -1 ? fname.substring(pos + 1) :
"";
if(extension.equals("xml"))
{
File result =
style(docs[i],target);
messager.progress(docs[i],result);
}
// else
copy file
}
for(int i = 0;i <
idirs;i++)
walk(dirs[i],new
File(target,dirs[i].getName()));
}
else
messager.fatal(new
XMException(
Resources.getString("notdirectory"),
new Object[] {source.getAbsolutePath()}));
}
protected File style(File sourceFile,File
targetDir)
throws XMException
{
try
{
String resultName =
sourceFile.getName();
int
pos =
resultName.lastIndexOf('.');
if(pos !=
-1)
resultName =
resultName.substring(0,pos);
resultName += extension;
File resultFile = new
File(targetDir,resultName);
if(resultFile.exists())
{
if(resultFile.lastModified() >= sourceFile.lastModified()
&&
resultFile.lastModified() >=
lastModified)
return null;
}
Transformer transformer =
templates.newTransformer();
transformer.transform(new
StreamSource(sourceFile),
new
StreamResult(resultFile));
return resultFile;
}
catch(TransformerException
e)
{
throw new
XMException(e);
}
}
}
walk() 遍歷目錄,應(yīng)用樣式表。它是通過列出所有目錄內(nèi)容,然后分成文件和子目錄開始的。接下來,它對每個(gè)文件應(yīng)用樣式,然后為子目錄遞歸地調(diào)用自身。
應(yīng)用樣式表是 style() 方法的職責(zé)。為了可移植性,DirectoryWalker 使用 TrAX(XML 的轉(zhuǎn)換 API)來與 XSLT 處理器交互。到目前為止,我已用 Xalan 測試了代碼(請參閱參考資料)。
未完待續(xù)……
您已經(jīng)可以下載和練習(xí) XM 代碼了。入口點(diǎn)是
org.ananas.xm.Console 類。它只使用兩個(gè)參數(shù):XML 文件所在的源目錄;以及將由 XM 創(chuàng)建的目標(biāo)目錄。確保樣式表名為
rules.xsl,并且它位于當(dāng)前目錄中。
我承認(rèn)當(dāng)前的版本做不了太多事情,只能用它來發(fā)布最簡單的網(wǎng)站。下一專欄將會有趣許多,因?yàn)槲矣?jì)劃添加一種機(jī)制來對文件系統(tǒng)應(yīng)用樣式表。
參考資料
- 通過單擊本文頂部或底部的討論,可以參加本文的論壇。
- 可以從 ananas.org 下載所有有關(guān)該項(xiàng)目的代碼,并訂閱有關(guān)該項(xiàng)目新聞和公告的郵件列表。
- XM 分別使用 Xalan 和 Xerces-J,作為 XML 語法分析器和 XSLT 處理器。
- 管理小型站點(diǎn)的網(wǎng)站管理員使用例如 SoftQuad HoTMetaL
PRO、Macromedia DreamOA 或 Microsoft
FrontPage 這樣的 HTML 編輯器就已足夠。
- 大型站點(diǎn)應(yīng)當(dāng)轉(zhuǎn)向那些高端內(nèi)容管理解決方案,例如 OpenMarket, Vignette 或 eContent。請注意,OpenMarket 是 IBM 合作伙伴,它在 WebSphere 上提供其內(nèi)容管理解決方案。
- Managing e-zines with JavaMail and XSLT(第 1 部分和第 2 部分)是另一篇有關(guān)將 XML 和 XSLT 用于發(fā)布的 developerWorks
文章。
- Cocoon 是一種開放源碼發(fā)布框架;它大量依賴于動(dòng)態(tài)代碼生成。
- 要了解 XML、XSLT 和 WebSphere 是如何使您的應(yīng)用程序更易于訪問的,請轉(zhuǎn)至 IBM WebSphere Transcoding Publisher V1.1: Extending Web Applications to
the Pervasive World。
- 可以在 developerWorks XML 專區(qū)中找到更多 XML 參考資料。
Beno顃 Marchal 是住在比利時(shí)那慕爾的顧問和作家。他是 XML by Example、 Applied XML Solutions 和 XML and the Enterprise 的作者。同時(shí)是 Gamelan 的專欄作家。www.marchal.com 上有其最新項(xiàng)目的詳細(xì)信息??梢酝ㄟ^ bmarchal@pineapplesoft.com 與他聯(lián)系。
- 1中國南玻集團(tuán)被要求承諾募資不投房產(chǎn)
- 2窗簾的浪漫風(fēng)情 精巧窗簾布藝讓家更美
- 3觀察樓市調(diào)控不會引發(fā)經(jīng)濟(jì)“二次探底”
- 4首鋼“畫餅”鋼鐵股充饑 機(jī)構(gòu)賣多買少
- 5木門加盟商如何選品牌 七大誤區(qū)需注意
- 6重慶模具業(yè)身陷重圍 外地模具吞掉八成
- 7三環(huán)發(fā)展股份推出SH-HVF-N型高壓變頻器
- 8雅保10月1日MARTINAL品牌阻燃劑產(chǎn)品提價(jià)
- 9櫥柜品牌提升銷售模式 與產(chǎn)品達(dá)到耦合
- 10賣場風(fēng)險(xiǎn)日漸增大 櫥柜網(wǎng)銷發(fā)展迅猛
- 11質(zhì)監(jiān)局聯(lián)合7部門開展建材市場秩序工作
- 12杜絕企業(yè)發(fā)展的知識缺口
- 13木家具不等于綠色家具 仿木家具選購注意要點(diǎn)
- 14河南交通投資集團(tuán)有限公司辦公OA軟件協(xié)同系統(tǒng)及企業(yè)介紹
- 15湖北黃梅縣22家石材開采礦點(diǎn)全部關(guān)停
- 16關(guān)注:生活家地板實(shí)現(xiàn)競爭力 完美更新
- 17促進(jìn)雙贏 五金廠該如何協(xié)助經(jīng)銷商開拓市場
- 18鋁型材行業(yè)“合縱連橫”忠旺成績矚目
- 19和成衛(wèi)浴 全球旗艦店揭幕儀式星光綻放
- 20武漢方圓金紅石型鈦白粉投產(chǎn)面市
- 21鋼鐵業(yè):大鋼廠上調(diào)9月出廠價(jià)符合預(yù)期
- 22上半年渝三峽涂料銷量同比增長27.63%
- 23東方雨虹機(jī)械化噴涂成功 應(yīng)用北京地鐵
- 24哈密依托豐富礦產(chǎn)資源有望成為西部石都
- 25產(chǎn)品升級 第五代門窗隔熱環(huán)保優(yōu)勢明顯
- 26泉州日用陶瓷出口量價(jià)齊增 態(tài)勢良好
- 272010巴西鋼鐵進(jìn)口有望創(chuàng)紀(jì)錄400萬噸
- 28行業(yè)視角 衛(wèi)浴集成吊頂?shù)投似穼⒈惶蕴?/a>
- 29逃離北上廣 二、三線城市成建材避風(fēng)港
- 30高端玻璃制造轉(zhuǎn)型進(jìn)行時(shí) 因業(yè)績低預(yù)期
成都公司:成都市成華區(qū)建設(shè)南路160號1層9號
重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓
版權(quán)所有:泛普軟件 渝ICP備14008431號-2 渝公網(wǎng)安備50011202501700號 咨詢電話:400-8352-114