xml+xslt+css+php 快速构建可扩展网站
作者:庞帆 shineyear@msn.com shinepf@gmail.com
版权:新浪网技术中国有限公司
参考:http://www.beigechina.com
1.让数据与显示分离
test.xml 数据:
<xml>
<title>test title</title>
<content>test content</content>
<top>banner</top>
<left>sidebar</left>
<body>main body</body>
<end>end of the page</end>
</xml>
test.xslt 模板:
<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xsl:output method=”html” encoding=”UTF-8″/>
<xsl:template name=”index” match=”xml”>
<xsl:value-of select=”document(”)/*/xsl:template[@name=’DOCTYPE’]/node()” disable-output-escaping=”yes”/>
</xsl:template>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″/>
<title>test</title>
<link rel=”stylesheet” type=”text/css” href=”test.css” />
</head>
<body>
<div class=”title”><xsl:value-of select=”title”/></div>
<div class=”content”><xsl:value-of select=”content” disable-output-escaping=”yes”/></div>
<div class=”top”><xsl:value-of select=”top”/></div>
<div class=”left”><xsl:value-of select=”left”/></div>
<div class=”body”><xsl:value-of select=”body”/></div>
<div class=”end”><xsl:value-of select=”end”/></div>
</body>
</html>
<xsl:template name=”DOCTYPE”>
<![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">]]>
</xsl:template>
</xsl:stylesheet>
2.网页自动生成
php 程序读入config文件根据文件中指定的目标文件名 和 数据文件名 以及 模板文件名生成目标页面
config 文件:
<xml>
<pages>
<page>
<name>test.html</name>
<xmlfile>test.xml</xmlfile>
<xslfile>test.xslt</xslfile>
</page>
</pages>
</xml>
php 代码:
<?php
$xml_file = “../conf/config”;
$name_tag = 0;
$xml_tag = 0;
$xsl_tag = 0;
$name = “”;
$arr = Array();
$i = 0;
function startElement($parser_instance, $element_name, $attrs)
{
global $name_tag;
global $xml_tag;
global $xsl_tag;
switch($element_name)
{
case “NAME” :
$name_tag = 1;
break;
case “XMLFILE” :
$xml_tag = 1;
break;
case “XSLFILE” :
$xsl_tag = 1;
break;
}
}
function characterData($parser_instance, $xml_data)
{
global $arr;
global $name_tag;
global $xml_tag;
global $xsl_tag;
global $name;
$xml_data = ltrim($xml_data);
if ($xml_data != “”)
{
if ($name_tag == 1)
{
$arr["$xml_data"] = Array();
$name = $xml_data;
$arr["$name"][0] = $name;
$name_tag = 0;
}
if ($xml_tag == 1)
{
$arr["$name"][1] = $xml_data;
$xml_tag = 0;
}
if ($xsl_tag == 1)
{
$arr["$name"][2] = $xml_data;
$xsl_tag = 0;
}
}
}
function endElement($parser_instance, $element_name)
{
}
function buildHtml($name, $xml, $xsl)
{
echo “$name\t$xml\t$xsl\n”;
$xslDoc = new DOMDocument();
$xslDoc->load(”$xsl”);
$xmlDoc = new DOMDocument();
$xmlDoc->load(”$xml”);
$proc = new XSLTProcessor();
$proc->importStylesheet($xslDoc);
$html = $proc->transformToXML($xmlDoc);
if (!($filehandler = fopen($name, “w+”)))
{
die(”could not open $name output”);
}
fwrite($filehandler, $html);
fclose($filehandler);
}
$parser = xml_parser_create();
xml_set_element_handler($parser, “startElement”, “endElement”);
xml_set_character_data_handler($parser, “characterData”);
if (!($filehandler = fopen($xml_file, “r”)))
{
die(”could not open XML input”);
}
while ($data = fread($filehandler, 4096))
{
if (!xml_parse($parser, $data, feof($filehandler)))
{
die(sprintf(”XML error: %s at line %d”,
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
}
fclose($filehandler);
xml_parser_free($parser);
foreach ($arr as $sub_arr)
{
$i = 0;
foreach ($sub_arr as $obj)
{
if ($i == 0)
{
$name = $obj;
}
if ($i == 1)
{
$xml = $obj;
}
if ($i == 2)
{
$xsl = $obj;
}
$i++;
}
buildHtml($name, $xml, $xsl);
}
?>
3.重新规划整个页面
xxcp
这样的分拆式设计可以使页面更灵活,随意修改任何部分都不会影响到其余的块,并且可以不断变换其中的某个块的数据 比如:body.xml 来生成更多新的页面, 特别适合新闻系统或论坛使用
top.xml:
<xml>
<top>banner</top>
</xml>
top.xslt:
<?xml version=”1.0″ encoding=”utf-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:xslAlt=”http://www.snee.com/xml/dummy”>
<xsl:namespace-alias stylesheet-prefix=”xslAlt” result-prefix=”xsl”/>
<xsl:template name=”top” match=”xml”>
<xslAlt:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xslAlt:template name=”top” match=”xml”>
<div class=”top”><xsl:value-of select=”top”/></div>
</xslAlt:template>
</xslAlt:stylesheet>
</xsl:template>
</xsl:stylesheet>
left.xml left.xslt
end.xml end.xslt
依此类推,同top
body.xml:
<xml>
<title>test title</title>
<content>test content</content>
<body>main body</body>
</xml>
body.xslt:
<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xsl:import href=”top_imp.xslt”/>
<xsl:import href=”left_imp.xslt”/>
<xsl:import href=”end_imp.xslt”/>
<xsl:output method=”html” encoding=”UTF-8″/>
<xsl:template name=”index” match=”xml”>
<xsl:value-of select=”document(”)/*/xsl:template[@name=’DOCTYPE’]/node()” disable-output-escaping=”yes”/>
<xsl:call-template name=”top”/>
<xsl:call-template name=”left”/>
<div class=”title”><xsl:value-of select=”title”/></div>
<div class=”content”><xsl:value-of select=”content” disable-output-escaping=”yes”/></div>
<div class=”body”><xsl:value-of select=”body”/></div>
<xsl:call-template name=”end”/>
</xsl:template>
<xsl:template name=”DOCTYPE”>
<![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">]]>
</xsl:template>
</xsl:stylesheet>
config 文件:
<xml>
<pages>
<page>
<name>top_imp.xslt</name>
<xmlfile>top.xml</xmlfile>
<xslfile>top.xslt</xslfile>
</page>
<page>
<name>left_imp.xslt</name>
<xmlfile>left.xml</xmlfile>
<xslfile>left.xslt</xslfile>
</page>
<page>
<name>end_imp.xslt</name>
<xmlfile>end.xml</xmlfile>
<xslfile>end.xslt</xslfile>
</page>
<page>
<name>test.html</name>
<xmlfile>body.xml</xmlfile>
<xslfile>body.xslt</xslfile>
</page>
</pages>
</xml>
4.数据的传递与重用
xxcp2
body.xml:
<xml>
<ad>test ad</ad>
<imglist>
<img>image_1.jpg</img>
<img>image_2.jpg</img>
<img>image_3.jpg</img>
</imglist>
<title>test title</title>
<content>test content</content>
<body>main body</body>
</xml>
body.xslt:
<?xml version=”1.0″ encoding=”UTF-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xsl:import href=”top_imp.xslt”/>
<xsl:import href=”left_imp.xslt”/>
<xsl:import href=”end_imp.xslt”/>
<xsl:output method=”html” encoding=”UTF-8″/>
<xsl:template name=”index” match=”xml”>
<xsl:value-of select=”document(”)/*/xsl:template[@name=’DOCTYPE’]/node()” disable-output-escaping=”yes”/>
<xsl:call-template name=”top”>
<xsl:with-param name=”top” select=”ad”/>
</xsl:call-template>
<xsl:call-template name=”left”>
<xsl:with-param name=”left” select=”imglist”/>
</xsl:call-template>
<div class=”title”><xsl:value-of select=”title”/></div>
<div class=”content”><xsl:value-of select=”content” disable-output-escaping=”yes”/></div>
<div class=”body”><xsl:value-of select=”body”/></div>
<xsl:call-template name=”end”/>
</xsl:template>
<xsl:template name=”DOCTYPE”>
<![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">]]>
</xsl:template>
</xsl:stylesheet>
left.xslt:
<?xml version=”1.0″ encoding=”utf-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:xslAlt=”http://www.snee.com/xml/dummy”>
<xsl:namespace-alias stylesheet-prefix=”xslAlt” result-prefix=”xsl”/>
<xsl:template name=”left” match=”xml”>
<xslAlt:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xslAlt:template name=”left” match=”xml”>
<xslAlt:param name=”left”/>
<div class=”img”>
<xslAlt:for-each select=”$left/img”>
<xslAlt:element name=”img”>
<xslAlt:attribute name=”src”><xslAlt:value-of select=”.”/></xslAlt:attribute>
<xslAlt:attribute name=”width”>70</xslAlt:attribute>
<xslAlt:attribute name=”height”>132</xslAlt:attribute>
</xslAlt:element>
</xslAlt:for-each>
</div>
<div class=”left”><xsl:value-of select=”left”/></div>
</xslAlt:template>
</xslAlt:stylesheet>
</xsl:template>
</xsl:stylesheet>
top.xslt:
<?xml version=”1.0″ encoding=”utf-8″?>
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” xmlns:xslAlt=”http://www.snee.com/xml/dummy”>
<xsl:namespace-alias stylesheet-prefix=”xslAlt” result-prefix=”xsl”/>
<xsl:template name=”top” match=”xml”>
<xslAlt:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
<xslAlt:template name=”top” match=”xml”>
<xslAlt:param name=”top”/>
<div class=”ad”><xslAlt:value-of select=”$top”/></div>
<div class=”top”><xsl:value-of select=”top”/></div>
</xslAlt:template>
</xslAlt:stylesheet>
</xsl:template>
</xsl:stylesheet>
config 文件不变, 运行PHP脚本后自动生成网页
5.提高CSS利用率
对CSS进行共享化处理, 即:页面中凡是可以共享的CSS风格, 全部提取出来, 如正文的文字风格与广告的文字风格, 就可以提取为一个CSS, 可以重复使用
高度提取的CSS可以帮助快速的网页开发, 甚至与数据提供者(XML数据编辑人员)进行共享,可以省去很多页面构建的麻烦