2

我有一个 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 或数据文档本身顶部的“查找”表中(我还不知道是哪一个)。

是否有允许这种模板的标准习语?有任何想法吗 ?

顺便一提; 数据文档当然包含许多不同的用户来创建

4

2 回答 2

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>

然后编写模板规则,通过替换参数来扩展消息。

于 2012-11-27T22:34:52.653 回答
1

@xiaoyi 是对的,展示了 using 的主要替代方案concat()。然而,这甚至比 更重符号concat(),因为你必须不断重复<xsl:value-of select="..." />

一个不错的选择是使用属性值模板(AVT):

[...]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}; &#10;[...]" />
  <q val="[...]CREATE TABLE {tablename}, blah blah; &#10;[...]" />
</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 环境中)。在这种情况下,您需要在之前在 XPath 表达式中使用它的任何地方nodeset( )环绕。$queries/

于 2012-11-27T21:26:11.203 回答