【发布时间】:2019-01-03 21:30:35
【问题描述】:
我一直在使用 XML + XSL 作为生成 HTML 电子邮件的工具。由于电子邮件代码严重依赖过时的标记和内联样式,我认为最好从格式化它所需的所有疯狂中提取实际内容。
但随着我走得更远,制作更多模板,我发现我越来越多地重复自己。有没有办法让 XSL 样式表变干,或者我是否必须用表现元素堵塞我的 XML 文件?我们以这段 XML 为例:
<root>
<headline>Hello</headline>
<button>Click me</button>
</root>
标题和按钮周围都需要一些 html(例如 H1 和 div),但由于我们讨论的是电子邮件,因此它们还需要一个表格单元格、一个表格行和一个表格,就像这样:
<table>
<tr>
<td>
<h1>Hello</h1>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div>Hello</div>
</td>
</tr>
</table>
因此,天真的解决方案是在每个元素的样式表中包含该表标记,如下所示:
<xsl:template match="headline">
<table>
<tr>
<td>
<h1>
<xsl:apply-templates/>
</h1>
</td>
</tr>
</table>
</xsl:template>
但是说在测试期间,我发现 Outlook 2007 中存在一个错误,这意味着所有这些包装表都需要一个附加属性:cell-padding=0;。如果我对表格标记进行了硬编码,我可能不得不使用几十个模板来传播该修复。
有没有办法创建包装表的“部分”模板,并在标题和按钮的各个模板中引用这些模板?
我知道我可以将标记更改为如下所示:
<root>
<table>
<headline>Hello</headline>
</table>
<table>
<button>Click me</button>
</table>
</root>
但这感觉就像把罐子踢到了路上。如果我发现由于 Gmail 移动应用程序中的错误,所有tds 都需要自己的特殊样式声明怎么办?那么解决方案是进入并更改标记,使其与最终输出无法区分,此时,XSL 模板真正在做什么?
我尝试了call-template 的解决方案,但没有成功。任何建议将不胜感激!
【问题讨论】:
-
您的处理器支持哪个版本的 XSLT?
-
我的处理器支持 XSLT 1.0,但我认为 Saxon 有一个开源处理器可以让我升级到 2.0。
-
在 XSLT 2.0 中,您可以利用
xsl:next-match指令。在 XST 1.0 中,您可以通过使用mode将模板应用到当前节点来执行类似的操作。