我正在整理一个简单的 XSL 样式表,以便同事可以预览他们正在浏览器中编辑的 XML。一个元素有许多不同的属性值,每一个都需要以不同的方式呈现。
<hi rend="b">
需要大胆,
<hi rend="b i">
需要粗体和斜体,等等。
我需要在 XSL 中做什么才能实现这一点?
我已经做了很多谷歌搜索,但还没有找到解决方案;也许这是一个非常基本的问题,但非常感谢任何帮助。
我正在整理一个简单的 XSL 样式表,以便同事可以预览他们正在浏览器中编辑的 XML。一个元素有许多不同的属性值,每一个都需要以不同的方式呈现。
<hi rend="b">
需要大胆,
<hi rend="b i">
需要粗体和斜体,等等。
我需要在 XSL 中做什么才能实现这一点?
我已经做了很多谷歌搜索,但还没有找到解决方案;也许这是一个非常基本的问题,但非常感谢任何帮助。
因为您在同事的浏览器中编写了预览 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>
@zx485 的解决方案如果有 2 个样式则需要 4 个模板,如果有 3 个则需要 8 个模板,如果有 4 个则需要 16 个:这不是很可扩展。
作为比较,这里有一个 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>