我正在整理一个简单的XSL样式表,以便同事可以预览他们在浏览器中编辑的XML。 一个元素具有许多不同的属性值,每个属性值都需要以不同的方式呈现。
<hi rend="b">
需要大胆,
<hi rend="b i">
需要粗体和斜体等等。
在XSL中我需要做些什么才能实现这一目标?
我已经做了很多谷歌搜索,还没有找到解决方案;也许这是一个非常基本的问题,但任何帮助都非常感激。
答案 0 :(得分:2)
因为您在浏览器中编写了同事预览XML,我假设您期望使用XSLT-1.0解决方案。以下模板会复制hi
元素,并使用b
和i
标记替换该属性。浏览器会忽略复制的hi
标记。
但是,在此解决方案中,您必须创建每个属性值的组合。
<xsl:template match="hi[contains(@rend,'i')]">
<xsl:copy>
<i><xsl:apply-templates /></i>
</xsl:copy>
</xsl:template>
<xsl:template match="hi[contains(@rend,'b')]">
<xsl:copy>
<b><xsl:apply-templates /></b>
</xsl:copy>
</xsl:template>
<xsl:template match="hi[contains(@rend,'i') and contains(@rend,'b')]">
<xsl:copy>
<i><b><xsl:apply-templates /></b></i>
</xsl:copy>
</xsl:template>
输出:
<hi><i><b>
...3...
</b></i></hi>
<hi><i>
...1...
</i></hi>
<hi><b>
...2...
</b></hi>
答案 1 :(得分:1)
@ zx485的解决方案需要4个模板(如果有2个样式),8个(如果有3个),16个(如果有4个):它们不是非常可扩展的。
为了比较,这里有一个XSLT 3.0解决方案(你可以在Saxon-JS中运行),它将处理一组完全开放的样式:
<xsl:function name="f:render" as="element()">
<xsl:param name="e" as="element()"/>
<xsl:param name="styles" as="xs:string*"/>
<xsl:choose>
<xsl:when test="empty($styles)">
<xsl:copy select="$e">
<xsl:copy-of select="@* except @rend"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{head($styles)}">
<xsl:sequence select="f:render($e, tail($styles))"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
然后
<xsl:template match="*[@rend]">
<xsl:sequence select="f:render(., tokenize(@rend))"/>
</xsl:template>