根据属性值对元素进行差异格式化

时间:2017-09-14 11:07:08

标签: xslt xsl-stylesheet

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

   <hi rend="b">

需要大胆,

   <hi rend="b i"> 

需要粗体和斜体等等。

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

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

2 个答案:

答案 0 :(得分: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>

答案 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>