xml - 带导入的 XSLT 变量范围
问题描述
我正在构建一个雄心勃勃且几乎注定失败的客户端 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 规范(很难阅读,除非您已经非常了解它)所以那里没有帮助。
解决方案
全局(顶级)变量以及其他命名声明(例如命名模板)的范围是整个样式表,即所有模块。当模块 A 导入模块 B 时,两个模块都可以声明变量 V,并且在 A 中的 V 声明在任何地方都使用,包括在 B 中(在规范的语言中,A 具有更高的导入优先级)。
如果您想在 XSLT 中编写一些雄心勃勃的东西,那么我建议您坚持理解规范。或者您可能更喜欢我的 Wrox/Wiley 的《 XSLT 程序员参考》一书——但它涵盖了 XSLT 2.0 而不是 1.0,除非您能找到旧版本。
我无法理解您所说的“当然,我现在知道 $xrcs-url 几乎没用,因为导入是在变量之前评估的”。导入不是“评估”的,它们是用于在编译时构造样式表的声明。我不知道你想用 $xrcs-url 做什么(你的代码似乎没有尝试使用它),原则上它似乎完全可用,尽管可能不是你想要的(但我不知道当然,您的意图是什么)。
顺便说一句,这里有一个带有两个模块的样式表:它有助于正确使用术语。
然后你说:“但是,当尝试使用这个样式表时,Firefox 会抱怨一些未指明的错误。” 好吧,它可能抱怨 xsl:import 声明在错误的位置。但更重要的是,在浏览器中运行 XSLT 代码并不是开发和测试的好方法。诊断很糟糕。使用专门的 IDE(例如 oXygen)效率更高(您说您雄心勃勃)。
推荐阅读
- python - 将模块从父文件导入到子文件中的模块
- android - 我如何从 Android 的其他布局中获取 EditText 的 id?
- r - 使用 R 包 NNMAPSlite 获取城市环境与死亡率数据集
- azure - 使用高级磁盘的 Azure VM 冷备份
- javascript - Javascript 功能未实现
- numpy - 如何索引/切片未知维度的 PyTorch 张量/numpy 数组的最后一个维度
- php - PHP:使用 rename() 时出现“找不到路径”错误。为什么?
- c# - Asp.net core 注册我们的应用服务是否意味着实例化类?
- java - 有没有更简洁的方法来执行此 if 语句?
- c++ - 尝试在 Visual Studio 上用 C++ 创建桌面应用程序