我想在XSLT中创建一个主模板,它可以存储在一个单独的文件中。每个其他页面样式表都使用xsl:import共享它。
master.xslt
<xsl:template match="Page">
<html>
<head>
</head>
<body>
<call-template name="Content"/>
</body>
</html>
</xsl:template>
<xsl:stylesheet>
page.xslt
<xsl:stylesheet>
<xsl:import href="master.xslt"/>
<xsl:template match="/">
<apply-templates match="Page"/>
</xsl:template>
<xsl:template name="Content">
... apply something page-specific
</xsl:template>
</xsl:stylesheet>
page.xml
<Page>
... something page-specific
</Page>
我能改进这个解决方案吗?
另一个决定(反对xslt精神)可能是这样的:
master.xslt
<xsl:template name="masterHead">
<html>
<head>
</head>
<body>
</xsl:template>
<xsl:template name=masterEnd>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
page.xslt
<xsl:stylesheet>
<xsl:import href="master.xslt"/>
<xsl:template match="/">
<call-template name=masterHead>
... apply something page-specific
<call-template name=masterEnd/>
</xsl:template>
</xsl:stylesheet>
我们不需要任何通用的根<Page>
元素。
答案 0 :(得分:1)
使用<xsl:import>
是正确的设计决策。这正是XSLT指令的主要用例。
可以更进一步 - 查找<xsl:apply-imports>
指令,以及导入的样式表如何应用模板,其中的操作和含义绝对不知道任何东西。后者称为Higher-Order-Functions,在XSLT中使用FXSL library实现(完全用XSLT编写)。
答案 1 :(得分:0)
这看起来对我来说是正确的...过去我曾经使用的很常见(尽管我经常使用<xsl:include/>
,但要么应该工作)。我可能做的主要改变是使匹配更明确(至少在master xslt中) - 即
<xsl:template match="/Page"> <!-- leading slash -->
所以它不会意外匹配其他位置的Page
元素(例如,数据分页,如<Page Index="3" Size="20"/>
)。
我做的另一件常见的事情是添加“*”匹配,如果我没有针对某个节点的更具体的匹配,则使用xsl:message
来引发错误。当你有错字等时,这会更加明显。
答案 2 :(得分:0)
我很高兴找到这个例子,因为我一直在寻找验证,这实际上是主/从模板设置的正确方法。 然而,提供的示例在tomcat上没有开箱即用 - 所以只是为了帮助那些只知道如何复制粘贴的人,这是一个有效的tomcat主/从文件集。
Master.xsl:
<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="iso-8859-15" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" indent="no"/>
<!-- http://stackoverflow.com/questions/646878/master-stylesheet-sharing-in-xslt -->
<xsl:template match="ms247">
<html>
<head>
<title>test</title>
</head>
<body>
<div style="border: 1px solid black; width: 200px; float: left; margin: 10px; padding: 5px;">
<xsl:call-template name="left"/>
</div>
<div style="border: 1px solid black; width: 200px; float: left; margin: 10px; padding: 5px;">
<xsl:call-template name="content"/>
</div>
<div style="border: 1px solid black; width: 200px; float: left; margin: 10px; padding: 5px;">
<xsl:call-template name="right"/>
</div>
</body>
</html>
</xsl:template>
<xsl:template name="content">
<span style="color: red">Content template is empty - overrule in page template.</span>
</xsl:template>
<xsl:template name="left">
<span style="color: red">Left template is empty - overrule in page template.</span>
</xsl:template>
<xsl:template name="right">
<span style="color: red">Right template is empty - overrule in page template.</span>
</xsl:template>
</xsl:stylesheet>
和slave.xsl:
<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="master.xsl"/>
<xsl:template name="content">
... apply something page-specific
</xsl:template>
<xsl:template name="right">
And we have RIGHT content!
<!-- Execute matching template which is NOT triggered automatically -->
<xsl:apply-templates select="params/param"/>
</xsl:template>
<!-- And we do not define any left template -->
<!-- Example -->
<xsl:template match="ms247/params/param">
Paramters on page: <xsl:value-of select="@name"/><br/>
</xsl:template>
</xsl:stylesheet>
希望这可以帮助别人 - 不要害羞地给我留言。