我正在重建我们网站的UI部分,它完全基于javascript/ajax (没有什么好的理由,而且效率很低),这样后端现在将完成大部分内容生成。它是一个C# .net应用程序。
几乎我们所有的页面(大概有40-50页)都有相同的基本布局。我对XSLT非常陌生,但我在MVC框架方面做了很多工作,比如Spring (java,使用Sitemesh进行布局)、Symfony (PHP)、一些rails以及其他一些框架。我喜欢有能力有一个或几个通用模板,然后有一个特定的“内容”部分,页面特定的东西去。我不知道XSLT是如何完成的。对于这个应用程序,我在支持xslt页面的xml中有一个可用的值,让我们称它为ContentXSL,它的值是我想要用于页面内容部分的xsl文件的名称。我知道这是不可能的,但最好用一下:
<xsl:call-template name="{$ContentXSL}" />然后我可以简单地把它放在内容部分..。但是这是不可能的,所以我需要一个大量的correct语句,它根据ContentPage变量调用正确的模板。这也意味着,在我的Layout.xsl文件中,我必须包含所有40-50个xsl文档。我想开销会很大,但我不确定。如果网站的流量很大,这是合理的做法吗?
其他常见的方法是什么呢?似乎大多数现代框架都允许您使用这种模式来装饰内容。在Symfony的情况下,它工作得很好,而且非常灵活(有槽之类的)。
我知道另一个潜在的解决方案是拥有40个独立的文件,这些文件都有相似的标记,并且包括特殊的部分,如页眉和页脚。这意味着,如果我想改变我的网站布局的总体结构,我将不得不编辑所有40-50页,尽管(非常烦人)。
更新--更多解释
我想进一步解释这一点,因为我有一些需要大量工程才能改变的要求。首先,后端将向我传递一些xml,它将使我知道网站的URL中有查询args。另外,它将把构建页面所需的数据(业务数据形式的数据,没有html或类似的东西)传递给我。数据看起来与此类似:
<xml>
<section>Blogs</section>
<page>showAll</section>
<data>
<blogs>
<blog>
<author>somebody</author>
<title></title>
<content>..</content>
</blog>
</blog>..</blog>
</blogs>
</data>
</xml>现在想要的是有一个这样的页面模板:
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
<xsl:output omit-xml-declaration='yes' method='html' media-type='text/html' indent='yes' />
<xsl:include href="Header.xsl"/>
<xsl:include href="Nav.xsl"/>
<xsl:template name='MainLayout' match='*'>
<html>
<head>
<title></title>
</head>
<body>
<div id="header"><xsl:call-template name="Header" /></div>
<div id="nav"><xsl:call-template name="Nav" /></div>
<div id="content">
[here is where i want to use the xsl from {/xml/section}/{/xml/page}.xsl]
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>现在,对于这个页面的内容,我将有以下文件:Blogs/howAll.xsl
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl='urn:schemas-microsoft-com:xslt'>
<xsl:output omit-xml-declaration='yes' method='html' media-type='text/html' indent='yes' />
<xsl:template name='Blogs_ShowAll'>
<div id="blogs-showAll">
..iterate over /xml/data/blogs converting to html
</div>
</xsl:template>
</xsl:stylesheet>到目前为止,解决方案是好的,但其中只有一个是我能够完全消化的(其中提到了包含所有xsl文件并使用xsl:选择正确的一个)。我不知道如何将FXSL方法应用于当前的问题。请注意,我不会反对使用sitemesh类型的方法,它指定html/body标记以及子元素中的所有内容,并将其替换到布局的内容div中的子元素的主体部分(如果子元素中有标题标记,则替换布局中的标题标记--类似的内容)。
发布于 2010-08-14 21:16:02
OP提供了他的问题的更多细节,这个答案提供了现在所要求的附加解决方案。
I.思想:
这个转换
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html>
<xsl:apply-templates select="*/page"/>
</html>
</xsl:template>
<xsl:template match="page[. = 'showAll']">
<!-- Transform all data to html -->
<xsl:apply-templates select="../*/blogs" mode="showAll"/>
</xsl:template>
<xsl:template match="page[. = 'showBrief']">
<!-- Transform the data to Summary html -->
<xsl:apply-templates select="../*/blogs" mode="showBrief"/>
</xsl:template>
<xsl:template match="blogs" mode="showAll">
<h1>All Blogs: </h1>
<table border="1">
<xsl:apply-templates mode="showAll"/>
</table>
</xsl:template>
<xsl:template match="blog" mode="showAll">
<tr>
<td>Blog of <xsl:value-of select="author"/></td>
<td><xsl:value-of select="title"/></td>
</tr>
<tr>
<td colspan="2"><xsl:apply-templates select="content/node()" mode="showAll"/></td>
</tr>
<xsl:if test="not(position()=last())">
<tr><td colspan="2"> </td></tr>
</xsl:if>
</xsl:template>
<xsl:template match="blogs" mode="showBrief">
<h1>Blogs Summary: </h1>
<table border="1">
<xsl:apply-templates mode="showBrief"/>
</table>
</xsl:template>
<xsl:template match="blog" mode="showBrief">
<tr>
<td>
<xsl:value-of select="concat(author, ': ', title)"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>应用于此XML文档(基于所提供的XML文本,但使其格式良好且更充实):
<xml>
<section>Blogs</section>
<page>showAll</page>
<data>
<blogs>
<blog>
<author>John Smith</author>
<title>All about golden fish</title>
<content>
Here I publish my latest achievements
in raising golden fish.
</content>
</blog>
<blog>
<author>Mary Jones</author>
<title>Knitting, Knitting, Knitting</title>
<content>
How to knit a sharf.
</content>
</blog>
</blogs>
</data>
</xml>生成所需的“显示所有”类型的输出。
<html>
<h1>All Blogs: </h1>
<table border="1">
<tr>
<td>Blog of John Smith</td>
<td>All about golden fish</td>
</tr>
<tr>
<td colspan="2">
Here I publish my latest achievements
in raising golden fish.
</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<td>Blog of Mary Jones</td>
<td>Knitting, Knitting, Knitting</td>
</tr>
<tr>
<td colspan="2">
How to knit a sharf.
</td>
</tr>
</table>
</html>现在,我们更改XML文档并用这个page替换元素。
<page>showBrief</page>当对更新的XML文档应用相同的转换时,它现在生成所需的摘要输出。
<html>
<h1>Blogs Summary: </h1>
<table border="1">
<tr>
<td>John Smith: All about golden fish</td>
</tr>
<tr>
<td>Mary Jones: Knitting, Knitting, Knitting</td>
</tr>
</table>
</html>II.下一步
实际上,在给定模式下,所有模板都将位于各自的xsl文件中,并将由主样式表导入:
因此,转换(主要样式表)成为
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="showAll.xsl"/>
<xsl:import href="showBrief.xsl"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html>
<xsl:apply-templates select="*/page"/>
</html>
</xsl:template>
</xsl:stylesheet>确实注意到
<xsl:choose>指令等。--这是xsl模板在动作中的真正力量。发布于 2010-08-13 01:29:03
虽然在所有版本的XSLT中在语法上都是非法的,但使用XSLT模板作为高阶函数的从十年前开始在 FXSL库 中实现和使用。
以下是如何实现这一目标的一些简化的想法:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="pFunction1">
<fun name="increment"/>
</xsl:param>
<xsl:param name="pFunction2">
<fun name="double"/>
</xsl:param>
<xsl:variable name="vFunIncrement" select=
"document('')/*/xsl:param[@name='pFunction1']/*"/>
<xsl:variable name="vFunDouble" select=
"document('')/*/xsl:param[@name='pFunction2']/*"/>
<xsl:variable name="vInput" select="."/>
<xsl:template match="/">
increment(<xsl:value-of select="$vInput"/>) = <xsl:text/>
<xsl:apply-templates select="$vFunIncrement">
<xsl:with-param name="parg1" select="$vInput"/>
</xsl:apply-templates>
double(<xsl:value-of select="$vInput"/>) = <xsl:text/>
<xsl:apply-templates select="$vFunDouble">
<xsl:with-param name="parg1" select="$vInput"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="fun[@name='double']">
<xsl:param name="parg1"/>
<xsl:value-of select="2*$parg1"/>
</xsl:template>
<xsl:template match="fun[@name='increment']">
<xsl:param name="parg1"/>
<xsl:value-of select="$parg1+1"/>
</xsl:template>
</xsl:stylesheet>当此转换应用于以下XML文档时,
<num>2</num>结果是
increment(2) = 3
double(2) = 4确实注意到
<fun>元素可以通过全局级别的参数从外部传递到转换。这意味着转换不知道将执行哪些函数。fun元素的name属性的模板来模拟。如果您想阅读和理解FXSL,以下是两种最好的材料:
发布于 2010-08-13 04:30:17
迪米特里的例子很好。
这里也有一种方法。一个很难看的解决方案,但能解决这个问题
primary.xsl
<xsl:variable name="ContentXSL" select="/your/xml/settings/@content" />
<!-- Reference templates -->
<xsl:include href="template1.xsl" />
<xsl:include href="template2.xsl" />
<xsl:include href="template3.xsl" />
<xsl:include href="template4.xsl" />
<xsl:template match="/">
<html>
<head>
<title>..</title>
</head>
</html>
<body>
<xsl:call-template name="getcontent" />
</body>
</xsl:template>
<xsl:template name="getcontent">
<xsl:choose>
<xsl:when test="$ContentXSL = 'template1'">
<xsl:apply-templates match="/your/xml/structure" mode="template1" />
</xsl:when>
<xsl:when test="$ContentXSL = 'template2'">
<xsl:apply-templates match="/your/xml/structure" mode="template2" />
</xsl:when>
<xsl:when test="$ContentXSL = 'template3'">
<xsl:apply-templates match="/your/xml/structure" mode="template3" />
</xsl:when>
<xsl:when test="$ContentXSL = 'template4'">
<xsl:apply-templates match="/your/xml/structure" mode="template4" />
</xsl:when>
<xsl:otherwise>
<!-- Default template? -->
<xsl:apply-templates match="/your/xml/structure" mode="template1" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>template1.xsl
<xsl:template match="/your/xml/structure" mode="template1">
Template 1<br />
</xsl:template>template2.xsl
<xsl:template match="/your/xml/structure" mode="template2">
Template 2<br />
</xsl:template>template3.xsl
<xsl:template match="/your/xml/structure" mode="template3">
Template 3<br />
</xsl:template>template4.xsl
<xsl:template match="/your/xml/structure" mode="template4">
Template 4<br />
</xsl:template>https://stackoverflow.com/questions/3473108
复制相似问题