SiteMesh允许您将模板文件定义为相当标准的html文件,然后是子页面,它将覆盖父项的各个部分.
例如,这是sitemesh的基本模板(装饰器):
<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %> <head> <title> <decorator:title default="SiteMesh Tutorial Example" /> - Site Title </title> <style type="text/css">@import "css/global.css";</style> <decorator:head /> <body> <div id="header"> <h2><a href="http://www.my-site.com/">Mysite.com</a> goes here</h2> </div> <div id="content"> <decorator:body /> </div> </body> </html>
然后这将是一个子页面的示例:
<html> <head> <title>Child Page</title> <style type='text/css'> p { margin: 10 } </style> </head> <body> Content Goes here </body> </html>
一旦装饰器应用于子页面,结果
包含装饰器:body所在的子页面的主体,以及装饰器:head也被替换等等.
非常简单它的工作原理和相当有效的组织网站的方式.
所以现在让我们说我们正在使用XSL / T而我们想要使用类似的结构,我们不会继续重新定义布局的样子,而是我们希望只定义一次(或者对于那些不是’非常相似),如果子模板有部分,我们会替换部分.
听起来这很简单,但问题是支持这个网站的数据看起来像(不是真正的博客网站,而只是我正在处理的一个例子)
<xml> <section>Blogs</section> <page>UserBlogs</page> <data> <blogs> <blog> <title>First Blog</title> <author>John Doe</author> <description>...</description> </blog> </blogs> </data> </xml>
所以现在让我们说我有一个这样的主模板:
<html> <head> <title><!-- replace this with child title --> - Site Title</title> <script src="common-scripts.js"></script> <style type="text/css">@import "common.css" </style> <!-- insert everything in the child <head> here except the title --> </head> <body> <div id="header">Header/log that stuff here</div> <div id="menu"> <ul><li><a href="#">Cat 1</a></li><li><a href="#">Cat 2</a></li></ul> </div> <div id="content"> <!-- replace this with everything between <body>...</body> in the child --> </div> <div id="footer">My Site,copyright,bla bla</div> </body> </html>
那么我想要做的就是从上面获取xml(关于博客的那个)并将其应用到我的子页面,并将该转换的结果应用到我的主模板(它将根据需要复制/应用元素) ).
我不确定是否有办法在一次转换中做到这一点.
目前架构是这样的,我提供了如图所示的xml,我必须将其构建成一个页面..我想也许我可以让主模板包含子模板,然后使用xsl:call-template包含在一个xsl:variable声明,用于捕获当前xml上的子模板的结果.我需要以某种方式将该转换的结果替换为主模板title / header / content部分.
知道如何做到这一点?
我在这个网站上看到:http://www.devguru.com/technologies/xslt/quickref/xslt_element_calltemplate.html
您可以在xsl:variable声明中捕获xsl:call-template的结果我只是混淆了如何使用该数据除了输出它之外…
任何帮助,将不胜感激
<xml> <section>Blogs</section> <page>UserBlogs</page> <data> <blogs> <blog> <title>First Blog</title> <author>John Doe</author> <description>...</description> </blog> </blogs> </data> </xml>
这个“master.xml”文档:
<html> <head> <title><!-- replace this with child title --> - My Site</title> <script src="common-scripts.js"></script> <style type="text/css">@import "common.css" </style> <!-- insert everything in the child <head> here except the title --> </head> <body> <div id="header">Header/log that stuff here</div> <div id="menu"> <ul> <li> <a href="#">Cat 1</a> </li> <li> <a href="#">Cat 2</a> </li> </ul> </div> <div id="content"> <!-- replace this with everything between <body>...</body> in the child --> </div> <div id="footer">My Site,bla bla</div> </body> </html>
这个“child.xml”文档:
<html> <head> <title>Child Page</title> <style type='text/css'>p { margin: 10 }</style> </head> <body> <h3 id="title">#</h3> <dl> <dt id="author">#</dt> <dd id="description">#</dd> </dl> </body> </html>
这个样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml"/> <xsl:variable name="child" select="document('child.xml')"/> <!-- From here to next comment could be in other stylesheet like "master.xsl" and included with "xsl:include" --> <xsl:variable name="master" select="document('master.xml')"/> <xsl:template match="@*|node()"> <xsl:param name="context"/> <xsl:copy> <xsl:apply-templates select="@*|node()"> <xsl:with-param name="context" select="$context"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="/"> <xsl:apply-templates select="$master/*"> <xsl:with-param name="context" select="/"/> </xsl:apply-templates> </xsl:template> <xsl:template match="div[@id='content']"> <xsl:param name="context"/> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:for-each select="$context/xml/data/blogs/blog"> <xsl:apply-templates select="$child/html/body/node()"> <xsl:with-param name="context" select="."/> </xsl:apply-templates> </xsl:for-each> </xsl:copy> </xsl:template> <xsl:template match="title/comment()"> <xsl:param name="context"/> <xsl:value-of select="$context/xml/page"/> </xsl:template> <xsl:template match="head/comment()"> <xsl:param name="context"/> <xsl:apply-templates select="$child/html/head/node()[not(self::title)]"> <xsl:with-param name="context" select="$context"/> </xsl:apply-templates> </xsl:template> <!-- Here ends the posible "master.xsl" to be included --> <xsl:template match="@id[.='title']|@id[.='author']|@id[.='description']"/> <xsl:template match="*[@id='title']/text()"> <xsl:param name="context"/> <xsl:value-of select="$context/title"/> </xsl:template> <xsl:template match="*[@id='author']/text()"> <xsl:param name="context"/> <xsl:value-of select="$context/author"/> </xsl:template> <xsl:template match="*[@id='description']/text()"> <xsl:param name="context"/> <xsl:value-of select="$context/description"/> </xsl:template> </xsl:stylesheet>
输出:
<html> <head> <title>UserBlogs - My Site</title> <script src="common-scripts.js"></script> <style type="text/css">@import "common.css" </style> <style type="text/css">p { margin: 10 }</style> </head> <body> <div id="header">Header/log that stuff here</div> <div id="menu"> <ul> <li> <a href="#">Cat 1</a> </li> <li> <a href="#">Cat 2</a> </li> </ul> </div> <div id="content"> <h3 id="title">First Blog</h3> <dl> <dt id="author">John Doe</dt> <dd id="description">...</dd> </dl> </div> <div id="footer">My Site,bla bla</div> </body> </html>
注意:这只是一个例子.有待改善.关于人口模式的主要问题:逻辑是横向布局,而不是数据,主要是身份变换;你需要在布局中加入一些锚点来引用数据(例如,通过自己的命名空间,通过特定的模式,如id =“include:some-data”等,这是开放性的改进);如果它们是@id,你需要删除那些锚;对于文本替换,在布局中使用虚拟文本节点,这简化了内容模板,仅使用xsl:value-of; “穷人的隧道模式”(Dimitre称)传递数据上下文,主要是因为迭代人口.其他问题:处理XHTML(优于HTML)时要注意:DOCTYPE主要用于IE7(松散改进的CSS处理,否则),在DTD中声明的空元素(否则与< br />的错误行为).可以自由查看我之前发布的网站,看看我是如何处理这些网站的.