我有一个XSLT(2.0)文件;它接受输入XML数据文件并创建DDL / SQL语句。 它工作得很好。但是它有点难以维护,因为它在'concat'语句中包含了很多格式化信息,如下所示:
<xsl:value-of select="concat('CREATE USER ',$username,' IDENTIFIED BY ',$password,';',$nl)"/>
我更喜欢做的是以这样的方式编码我的SQL语句:
<some-enclosing-elements>[...]CREATE USER <username/>, identified by <password/>; [literally a newline here][...]</some-enclosing-elements>
我可能会将这种格式保存在XML数据文件本身的XSLT或数据文档的顶部的“查找”表中(我还无法解决)。
是否有允许这种模板的标准习语? 有什么想法吗?
顺便说一下;当然,数据文档包含许多不同的用户答案 0 :(得分:2)
AVT方法对我的品味有点过于狡猾。我倾向于依赖xsl:value-of:
完成的隐式连接(在2.0中)<xsl:value-of select="'CREATE USER', $username, 'identified by', $password"/>
我在这种文本模板很重要的应用程序中使用的另一种方法是在XSLT中基本上编写自己的模板引擎;有一个“消息文件”,其中包含
形式的消息模板<message nr="1">CREATE USER <p:user/> IDENTIFIED BY <p:password/></message>
然后编写模板规则以通过替换参数来扩展消息。
答案 1 :(得分:1)
@xiaoyi是对的,显示了使用concat()
的主要替代方案。然而,由于你必须不断重复concat()
,这比<xsl:value-of select="..." />
更加重要。
一个不错的选择是使用attribute value templates(AVTs):
[...]CREATE USER {username}, identified by {password};
[...]
但ATV仅适用于(某些)属性,不适用于文本节点(直接)。你如何将它们用于此目的?
XSLT 2.0的一种方法是使用AVT创建一个带有属性的新文字结果元素;使用AVT指定该属性的值;然后选择新属性的值:
<xsl:variable name="query">
<dummy val="[...]CREATE USER {username}, identified by {password};
[...]" />
</xsl:variable>
<xsl:value-of select="$query//@val" />
是的,每个格式化字符串有一些显着的开销,但字符串中每个字段的开销非常小。你可以像这样一起做几个字符串:
<xsl:variable name="queries">
<q val="[...]CREATE USER {username}, identified by {password}; [...]" />
<q val="[...]CREATE TABLE {tablename}, blah blah; [...]" />
</xsl:variable>
<xsl:value-of select="$queries/q[1]/@val" />
<xsl:value-of select="$queries/q[2]/@val" />
您可以使用上述位置索引,或使用id
属性来标识每个字符串。
我没有看到其他地方提倡的这种方法,所以我很想知道其他人对此的看法。
考虑到迈克尔凯的答案所显示的更简单的方法,我认为这样做没有任何意义。我想这可以解释为什么其他人没有提倡这种方法。 : - )
我能想到这种方法可能仍然有用的唯一情况是,如果你不能使用XSLT 2.0,但你可以访问nodeset()
扩展功能(例如在IE或.NET环境中) )。在这种情况下,您需要在nodeset( )
之前的XPath表达式中将$queries
包裹在/
左右。