XSLT 样式表是一个 XML 文档,这与涉及将 XML 转换为 XML 的任何其他问题没有什么不同。在这种情况下,您似乎希望保持大部分输入文件(即初始样式表)相同,但将任何内容替换<xsl:value-of select="$companyName" />
为固定值。这可以通过基于“身份模板”的常用方法来完成,将所有输入复制到输出不变,除非被更具体的模板覆盖。在这种情况下,“更具体的模板”是与该特定value-of
元素匹配的模板。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- treat whitespace the same as an XSLT processor would - ignore text nodes
containing only whitespace, except within xsl:text -->
<xsl:strip-space elements="*" />
<xsl:preserve-space elements="xsl:text" />
<xsl:output method="xml" indent="yes" />
<!-- the parameter you describe in the question -->
<xsl:param name="companyName" select="''"/>
<!-- the identity template -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<!-- handling for the specific value-of element -->
<xsl:template match="xsl:value-of[@select = '$companyName']">
<xsl:value-of select="$companyName" />
</xsl:template>
</xsl:stylesheet>
最后一个模板的match
表达式正在查找由美元符号后跟 组成的字符串companyName
,而不是此样式表中的参数值,而select
实际上将参数值作为文本节点插入。
但是,如果不是尝试替换原始样式表中使用参数值的位置(例如,上面会遗漏在更复杂的表达式中使用值的任何地方,例如concat($companyName, ' (company)')
),它可能会更健壮,您只需重新-将参数的定义写为variable
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<!-- the parameter you describe in the question -->
<xsl:param name="companyName" select="''"/>
<!-- the identity template -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<!-- handling for the specific param element -->
<xsl:template match="/xsl:stylesheet/xsl:param[@name = 'companyName']">
<xsl:element name="xsl:variable">
<xsl:attribute name="name">companyName</xsl:attribute>
<xsl:value-of select="$companyName" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这将转换输入样式表,例如
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="companyName" select="''" />
<xsl:template match="/">
<xsl:element name="Promotions">
<xsl:attribute name="CompanyName">
<xsl:value-of select="$companyName"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
进入
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="companyName">abc</xsl:variable>
<xsl:template match="/">
<xsl:element name="Promotions">
<xsl:attribute name="CompanyName">
<xsl:value-of select="$companyName"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这给出了完全相同的行为,但companyName
现在是硬编码而不是参数化。我去生成<xsl:variable name="...">value</xsl:variable>
而不是<xsl:variable name="..." select="'value'" />
允许value
可能包含单引号字符(例如“Sainsbury's”) - 使用文本内容通常被认为效率较低,因为它会生成一个额外的节点但它可以在值包含单引号,或双引号,甚至在同一字符串中的两种类型。