根据属性值对元素进行不同格式设置

Differential formatting for elements according to attribute values

我正在整理一个简单的 XSL 样式表,以便同事可以预览 XML 他们正在浏览器中编辑的内容。 一个元素有很多不同的属性值,每一个都需要不同的渲染。

   <hi rend="b">

需要加粗,

   <hi rend="b i"> 

需要加粗斜体等。

我需要在 XSL 中做什么才能做到这一点?

我已经进行了大量的谷歌搜索,但还没有找到解决方案;也许这是一个非常基本的问题,但非常感谢收到的任何帮助。

因为您在同事的浏览器中编写了预览 XML,所以我假设您期望 XSLT-1.0 解决方案。以下模板复制 hi 元素并将该属性替换为 bi 标记。复制的 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>