XSLT 样式表设计模式 - 将不同样式表中的通用模板和特定模板分开
我想知道 XSLT 样式表设计模式中是否有一种好的方法来分离公共数据表示和特定数据表示。
我正在尝试,但感到非常困惑和迷失。如果我可以阅读有关如何更好地分离 XSLT 样式表的任何建议、技巧和提示,我将不胜感激。另外,非常感谢您对下面的示例提供帮助,因为它不起作用=/谢谢!
我需要创建各种具有不同外观的 HTML 文档,以重用某些数据。例如文档日期、签名详细信息(姓名、职位)等。另外,我使用了相当多的全局变量(因为 XML 的结构不好并且数据在整个文档中重复使用)。
我试图做的就是移动所有在一个样式表中创建通用 HTML 结构的模板,然后所有特定位都将位于它们自己的样式表中。
类似于以下内容:
常见的 templatetes 样式表“commonTemplates.xsl”
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Variables Local -->
...
<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system="http://www.w3.org/TR/html4/loose.dtd" indent="yes" />
<xsl:template match="/Bookings">
<html>
<head>
<!-- populated by a template in a specific stylesheet -->
<title><xsl:call-template name="docTitle"/></title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<!-- general template for date -->
<xsl:template match="/Bookings/Booking" name="docDate">
<p class="date"><xsl:value-of select="./@Date"/></p>
</xsl:template>
<!-- general template for signature -->
<xsl:template match="/Bookings/Booking/Users" name="signature">
<xsl:param name="signatureLine" select="'Yours sincerely,'"/>
<div id="signature">
<p><xsl:value-of select="$signatureLine"/></p>
<p class="details">
<!-- populated by a template in a specific stylesheet -->
<xsl:apply-templates select="." mode="signature"/>
</p>
</div>
</xsl:template>
<!-- dummy templates signatures otherwise it complains that there is no such template -->
<xsl:template name="docTitle"/>
</xsl:stylesheet>
特定的 templatetes 样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Imports -->
<xsl:import href="commonTemplates.xsl"/>
<!-- BODY CONTENT OF HTML PAGE -->
<xsl:template match="/Bookings/Booking">
<xsl:call-template name="docDate"/>
<!-- document's content -->
<div>
<xsl:call-template name="content" />
</div>
</xsl:template>
<xsl:template name="docTitle">
<xsl:text>Here is the document title</xsl:text>
</xsl:template>
<!-- some content at the end of which signature should be inserted -->
<xsl:template name="content">
<p>SOME CONTENT</p>
<xsl:apply-templates />
</xsl:template>
<!-- specific rule to insert appropriate data for signature -->
<xsl:template match="/Bookings/Booking/Users" mode="signature">
<span class="name"><xsl:value-of select="./@Name"/></span>
<span class="job"><xsl:value-of select="./@Title"/></span>
</xsl:template>
</xsl:stylesheet>
不幸的是,签名模板不起作用,我不明白为什么:( 但它对 docTitle 有效。
结果 HTML 看起来像这样:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<p class="date">16 February 2010</p>
<div id="secondDeposit">
<p>SOME CONTENT</p>
<!-- here I get lots of empty space -->
</div>
</body>
我想知道这样的想法是否可以普遍实施以及如何正确执行,显然我的想法行不通。
另外,在这种情况下哪种方法更好:包含或导入样式表?我认为使用其中之一我不需要再次列出所有变量。
我将不胜感激任何帮助!很抱歉这篇文章很长,如果不清楚的话。
谢谢你!
I was wondering if there is a good approach in XSLT stylesheet design pattern to separate common and specific data representation.
I was trying, but got very confused and lost. I would appreciate any advice, tips, hints where I can read up on how to better separate XSLT stylesheets. And also, would really appreciate help with the example below as it doesn't work =/ THANK YOU!
I need to create a variety of HTML docs with different looks that would reuse some of the data. For example date of a document, signature details (name, job title) and so on. Also, I'm using quite a lot of global variables (because XML isn't structured well and data reused throughout a doc).
What I was trying to do, is to move all the templates that would create a common HTML structure in one stylesheet and then all specific bits will be in their own stylesheet.
Something like the following:
Common templetes stylesheet "commonTemplates.xsl"
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Variables Local -->
...
<xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system="http://www.w3.org/TR/html4/loose.dtd" indent="yes" />
<xsl:template match="/Bookings">
<html>
<head>
<!-- populated by a template in a specific stylesheet -->
<title><xsl:call-template name="docTitle"/></title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<!-- general template for date -->
<xsl:template match="/Bookings/Booking" name="docDate">
<p class="date"><xsl:value-of select="./@Date"/></p>
</xsl:template>
<!-- general template for signature -->
<xsl:template match="/Bookings/Booking/Users" name="signature">
<xsl:param name="signatureLine" select="'Yours sincerely,'"/>
<div id="signature">
<p><xsl:value-of select="$signatureLine"/></p>
<p class="details">
<!-- populated by a template in a specific stylesheet -->
<xsl:apply-templates select="." mode="signature"/>
</p>
</div>
</xsl:template>
<!-- dummy templates signatures otherwise it complains that there is no such template -->
<xsl:template name="docTitle"/>
</xsl:stylesheet>
Specific templetes stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Imports -->
<xsl:import href="commonTemplates.xsl"/>
<!-- BODY CONTENT OF HTML PAGE -->
<xsl:template match="/Bookings/Booking">
<xsl:call-template name="docDate"/>
<!-- document's content -->
<div>
<xsl:call-template name="content" />
</div>
</xsl:template>
<xsl:template name="docTitle">
<xsl:text>Here is the document title</xsl:text>
</xsl:template>
<!-- some content at the end of which signature should be inserted -->
<xsl:template name="content">
<p>SOME CONTENT</p>
<xsl:apply-templates />
</xsl:template>
<!-- specific rule to insert appropriate data for signature -->
<xsl:template match="/Bookings/Booking/Users" mode="signature">
<span class="name"><xsl:value-of select="./@Name"/></span>
<span class="job"><xsl:value-of select="./@Title"/></span>
</xsl:template>
</xsl:stylesheet>
Unfortunately, the template for signature doesn't work and I can't figure out why :( It does for the docTitle though.
The results HTML looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<p class="date">16 February 2010</p>
<div id="secondDeposit">
<p>SOME CONTENT</p>
<!-- here I get lots of empty space -->
</div>
</body>
I was wondering if such idea could be implemented in general and how to do it properly, obviously mine doesn't work.
Also, which approach will be better in this case: include or import stylesheet? I think with one of them I don't need to list all the variables again.
I would appreciate any help! Sorry for a long post and if it's not as clear.
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我使用以下方法:
模板文件 (/templates/Main.xslt)
函数文件 (/functions/General.xslt)
页面文件 ( /default.xslt)
其中有一些用于在模板中定义不同的布局。这是您在进行转换时调用的 XSLT 文件。
I use the following method:
Template File (/templates/Main.xslt)
Functions File (/functions/General.xslt)
Page File (/default.xslt)
There will be a few of these to define different layouts within the template. This is the XSLT file you call when doing your transformation.
建议的最佳做法是在样式表文件中累积常用模板,这些模板将由特定的 XSLT 应用程序导入。这些有用的 xstylesheet 文件的集合构成了有用的库。
当然,导入的样式表模块通常会导入其他样式表模块。
一个示例是用于 XSLT 中函数式编程的 FXSL 库。请研究 XSLT 应用程序(示例 testxxx.xsl 文件)如何导入它们所需的功能。
It is a recommended best practive to accumulate commonly used templates in stylesheet files that will be imported by specific XSLT applications. Collections of such useful xstylesheet files make useful libraries.
Of course, a stylesheet module that is imported often imports other stylesheet modules.
An example is the FXSL library for functional programming in XSLT. Do look into how XSLT applications (the example testxxx.xsl files) import the functionality they need.