John Fleck
libxslt 0.4版的教程
版权所有,2001 John Fleck
翻译,2007 Ou Lanhui
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license can be found here.
目录
介绍
主要功能
准备解析
解析样式表
解析输入文件
应用样式表
保存结果
参数
清理
附录 代码
摘要
使用libxslt库建立一个例程的教程是执行XSLT转换,将一个XML文件转换到HTML格式。
介绍
可扩展标记语言(XML)是全球信息网协会为了结构化文本格式数据交换工作而制订的标准。由于它的通用性,现在十分流行。每台电脑都可以读取文本文件。有正确的工具,任何一台电脑都可以阅读其它电脑的XML文件。
这些工具中最重要的之一就是XSLT:可扩展的样式表语言转换。XSLT是一种可声明的语言,允许你使用样式表将你的XML转换至任何一种文本输出。libxslt提供执行转换的相关函数。
libxslt是一个由Daniel Veillard为GNOME项目编写的免费的C语言库,允许你编写执行XSLT转换的程序。
注意
虽然libxslt是在GNOME项目的赞助之下编写的,但是它并不依赖于任何GNOME库。在本教程中就没有使用。
本教程举例说明了一个读取XML文件,应用样式表然后保存输出结果的简单程序。这不是一个你自己想要创的程序。xsltproc是在libxslt包所包含的一个做相同的事情但是更健壮和全功能的程序。本例中所编写的这个程序是为了说明libxslt的功能而设计的xsltproc的一个裁减版本的程序。
xsltproc的全部代码在libxslt发行包的xsltproc.c文件里。它也可以在网站上获得。
引用:
* W3C XML页面
* W3C XSL页面
* libxslt页面
主要功能
目录
准备解析
解析样式表
解析输入文件
应用样式表
保存结果
参数
清理
想转换一个XML文件,你必须执行以下三个函数:
1. 解析输入文件
2. 解析样式表
3. 应用样式表
准备解析
在你可以开始解析输入文件或者样式表之前,你需要执行一些步骤或者设置实体的处理方式。这些步骤对于libxslt来说不是唯一的。一些解析XML文件的libxml2程序可能会采用相似的步骤。
首先,你需要设置一些libxml的内部参数。传递一个整数1给xmlSubstituteEntitiesDefault函数,这将告诉libxml2的解析器置换实体内容就象解析你的文件。(传入0则libxml2不进行对应的置换)
其次,把xmlLoadExtDtdDefaultValue的值设成等于1。这将告诉libxml装载外部实体子集。如果你不这样做,当你的输入文件包含外部实体子集的时候,将会出错。
解析样式表
解析样式表使用一个简单的函数调用,需要一个xmlChar类型的变量:
cur = xsltParseStylesheetFile((const xmlChar *)argv[i]);
在这种情况下,我将从命令行参数传入的样式表文件名转换成xmlChar类型。返回值是xsltStylesheetPtr类型的值,是一个包含样式表树和其它关于样式表信息的内存结构。它可以被直接操作,但是在本例中不需要如此。
解析输入文件
使用一个函数调用解析输入的文件:
doc = xmlParseFile(argv[i]);
这个函数会返回一个xmlDocPtr类型的指针,一个包含文档树的内存结构。这个结构可以直接被操作,但是在这个例子里你不需要这样做。
应用样式表
现在你已经有表达文档的树和内存中的样式表了,可以对文档应用样式表了。实现这一功能的函数是xsltApplyStylesheet:
res = xsltApplyStylesheet(cur, doc, params);
这个函数使用一个xsltStylesheetPtr和一个xmlDocPtr类型做为参数,即前两个函数返回的值。第三个变量,params用来传入为样式表传入XSLT参数。它是一个空结束的静态字符串类型的名称/值对数组。
保存结果
libxslt包括了一族用来保存结果的函数。对于这个例子,使用了xsltSaveResultToFile,结果将被保存到:
xsltSaveResultToFile(stdout, res, cur);
注意
libxml也包含输出函数,如xmlSaveFile,它也可以在这里使用。然而,如果这里没有使用libxslt的保存函数,在样式表中包含的输出相关信息,如使用的编码声明就会丢失。
参数
在XSLT中,参数可以作为向样式表传递附加信息的途径之一。 libxslt允许将XSLT参数作为一个值传入xsltApplyStylesheet。
在教学的例程和xsltproc,就是教程例子所基于的那个程序,参数的传递采用键-值对来进行。程序从命令行收集这些内容,并将它们插入到params数组,然后将它们传给对应的函数。数组中的最后一个元素被设置成NULL。
注意
如果被传递的参数是一个字符串而不是XSLT节点,则它会被忽略。在教程的程序中,对于教程产生的程序,将如下实现:tutorial]$ ./libxslt_tutorial --param rootid "'asect1'" stylesheet.xsl filename.xml
清理
你完成这些工作之后,libxslt和libxml提供了释放已分配内存的函数。
xsltFreeStylesheet(cur);1
xmlFreeDoc(res);2
xmlFreeDoc(doc);3
xsltCleanupGlobals();4
xmlCleanupParser();5
1 释放你的样式表使用的内存。
2 释放结果文档使用的内存。
3 释放原始文档使用的内存。
4 释放libxslt全局变量使用的内存。
5 释放XML解析使用的内存。
附录. 源代码
libxslt_tutorial.c
/*
* libxslt_tutorial.c: demo program for the XSL Transformation 1.0 engine
*
* based on xsltproc.c, by Daniel.Veillard@imag.fr
* by John Fleck
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
extern int xmlLoadExtDtdDefaultValue;
static void usage(const char *name) {
printf("Usage: %s [options] stylesheet file [file ...]\n", name);
printf(" --param name value : pass a (parameter,value) pair\n");
}
int
main(int argc, char **argv) {
int i;
const char *params[16 + 1];
int nbparams = 0;
xsltStylesheetPtr cur = NULL;
xmlDocPtr doc, res;
if (argc <= 1) {
usage(argv[0]);
return(1);
}
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
break;
if ((!strcmp(argv[i], "-param")) ||
(!strcmp(argv[i], "--param"))) {
i++;
params[nbparams++] = argv[i++];
params[nbparams++] = argv[i];
if (nbparams >= 16) {
fprintf(stderr, "too many params\n");
return (1);
}
} else {
fprintf(stderr, "Unknown option %s\n", argv[i]);
usage(argv[0]);
return (1);
}
}
params[nbparams] = NULL;
xmlSubstituteEntitiesDefault(1);
xmlLoadExtDtdDefaultValue = 1;
cur = xsltParseStylesheetFile((const xmlChar *)argv[i]);
i++;
doc = xmlParseFile(argv[i]);
res = xsltApplyStylesheet(cur, doc, params);
xsltSaveResultToFile(stdout, res, cur);
xsltFreeStylesheet(cur);
xmlFreeDoc(res);
xmlFreeDoc(doc);
xsltCleanupGlobals();
xmlCleanupParser();
return(0);
}
原文在此。有一些地方翻译的有问题,欢迎指导。标签: C, C++, XML, XSLT, 学习, 翻译