我正在构建一个雄心勃勃且几乎可以肯定注定要失败的客户端CMS(使用XSLT 1.0,大多数浏览器都支持)。作为其中的一部分,我希望将template.xsl
用作样式表,并将业务逻辑包含在config.xsl
中。
这是我拥有的那种XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/XRCS/xrcs/template.xsl" type="text/xsl"?>
<xrcs:page id="/"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xrcs="xrcs:xrcs">
<xrcs:title>XRCS Home Page</xrcs:title>
<xrcs:content>
Hello I am some HTML!
<p>
Paragraphs!
</p>
<h2>Headings!</h2>
<p>
More paragraphs!
</p>
</xrcs:content>
</xrcs:page>
首先,我希望页面标题可以从config.xsl
中进行自定义。我认为这将非常简单:
template.xsl
-实际的样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xrcs="xrcs:xrcs"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:import href="config.xsl" />
<!-- DOCTYPE from
https://stackoverflow.com/a/22302701/522375 -->
<xsl:output method="xml"
doctype-system="about:legacy-compat" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="$site-name" /></title>
</head>
<body>
<h1><xsl:value-of select="/xrcs:page/xrcs:title" /></h1>
<xsl:copy-of select="/xrcs:page/xrcs:content/*" />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
config.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xrcs="xrcs:xrcs"
xmlns="http://www.w3.org/1999/xhtml">
<!-- Global variables -->
<xsl:variable name="site-name" select="'XRCS'" />
<xsl:variable name="xrcs-url" select="'/XRCS/xrcs'" />
<!-- Extensions -->
<xsl:import href="extensions/core.xsl" />
<xsl:import href="extensions/include.xsl" />
<xsl:import href="extensions/citations.xsl" />
</xsl:stylesheet>
extensions/*
都是空的<xsl:stylesheet>
元素。当然,我现在知道$xrcs-url
几乎没有用,因为导入是在变量之前求值的。但是,Firefox在尝试使用此样式表时会抱怨一些未指定的错误。
此样式表(我已用变量定义替换了导入),效果很好:
template.xsl
-实际的样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xrcs="xrcs:xrcs"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:variable name="site-name" select="'XRCS'" />
<!-- DOCTYPE from
https://stackoverflow.com/a/22302701/522375 -->
<xsl:output method="xml"
doctype-system="about:legacy-compat" />
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="$site-name" /></title>
</head>
<body>
<h1><xsl:value-of select="/xrcs:page/xrcs:title" /></h1>
<xsl:copy-of select="/xrcs:page/xrcs:content/*" />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
为什么?!
到目前为止,我唯一提出的解释是变量是特定于文件的。如果是这样,我会非常非常烦恼,但是我想我可以为配置定义另一个模式,然后使用该$xrcs-url
变量...
我的假设正确吗?这些变量是否特定于文件?我没有找到有关它的文档,并且XSLT规范是W3规范(除非您已经非常了解它,否则很难阅读),所以那里没有任何帮助。
答案 0 :(得分:1)
全局(顶级)变量以及其他命名声明(例如命名模板)的范围是整个样式表,即所有模块。当模块A导入模块B时,两个模块都可以声明变量V,并且A中的V声明在各处都使用,包括在B中使用(按照规范的语言,A具有更高的导入优先级)。
如果您试图在XSLT中编写一些雄心勃勃的东西,那么我建议您坚持不懈地理解规范。或者,您可能更喜欢Wrox / Wiley的《 XSLT程序员参考》( XSLT程序员参考)-但它涵盖的是XSLT 2.0,而不是1.0,除非可以找到较旧的版本。
我很难理解您的意思是“当然,现在我知道$ xrcs-url几乎是无用的,因为导入是在变量之前求值的。” 导入不被“评估”,它们是用于在编译时构造样式表的声明。我不知道您想使用$ xrcs-url做什么(您的代码似乎没有尝试使用它),原则上似乎完全可以使用,尽管也许不是您的意图(但我不知道)当然是您想要的)。
顺便说一句,这里有一个样式表,其中包含两个模块:有助于正确理解术语。
然后,您说:“但是,Firefox在尝试使用此样式表时抱怨某些未指定的错误。”好吧,可能是在抱怨xsl:import声明在错误的位置。但更重要的是,在浏览器中运行XSLT代码并不是开发和测试的好方法。诊断很糟糕。使用专用的IDE(例如oXygen)会更有效率(您说自己很雄心勃勃)。
答案 1 :(得分:0)
<xsl:import />
必须出现在<xsl:stylesheet />
的任何其他子元素之前。那是我得到错误的直接原因。
我接受迈克尔·凯(Michael Kay)的回答,因为它实际上是这样说的,即使我错过了它,花了几天的时间自己弄清楚!