0

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

   <hi rend="b">

需要大胆,

   <hi rend="b i"> 

需要粗体和斜体,等等。

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

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

4

2 回答 2

2

因为您在同事的浏览器中编写了预览 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>
于 2017-09-14T11:25:32.027 回答
1

@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>
于 2017-09-14T13:29:54.353 回答