xsl disable-output-escaping copy-of

时间:2015-07-20 13:35:32

标签: xml xslt

我有一个像这样的xsl:模板:

<xsl:template name="box2">
<xsl:param name="txt"/>
  <div class="panel1">
    <xsl:value-of select="$txt" disable-output-escaping="yes" />
  </div>
</xsl:template>
然后我用param打电话给templete:

<xsl:call-template name="box2">
<xsl:with-param name="txt">
    &lt;b&gt;First&lt;/b&gt;
    <b>Second</b>
</xsl:with-param>
</xsl:call-template>

结果是这样的:

<div class="panel1">
    <b>First</b>
    Second
</div>

我尝试使用copy-of value-of,然后结果是:

<div class="panel1">
    &lt;b&gt;First&lt;/b&gt;
    <b>Second</b>
</div>

是一种获得这样结果的方法:

<div class="panel1">
    <b>First</b>;
    <b>Second</b>
</div>

1 个答案:

答案 0 :(得分:1)

http://www.w3.org/TR/xslt#copying所示,disable-output-escaping上不允许xsl:copy-of。如果您使用的是XSLT 1.0,那么您的参数是一个结果树片段,您可以将其转换为节点集,然后您可以将模板应用于您使用value-of disable-output-escaping的文本节点的节点。对于使用copy-of的元素节点:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl">

<xsl:template name="box2">
  <xsl:param name="rtf"/>
  <div class="panel1">
    <xsl:apply-templates select="exsl:node-set($rtf)/node()" mode="doe"/>
  </div>
</xsl:template>

<xsl:template match="text()" mode="doe">
    <xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

<xsl:template match="*" mode="doe">
    <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="/">
    <xsl:call-template name="box2">
      <xsl:with-param name="rtf">
      &lt;b&gt;First&lt;/b&gt;
      <b>Second</b>
      </xsl:with-param>
    </xsl:call-template>
</xsl:template>
</xsl:transform>

有关输出

的示例,请参阅http://xsltransform.net/jyH9rN9
<div class="panel1">
      <b>First</b>
      <b>Second</b></div>

请注意,Mozilla浏览器不支持disable-output-escaping,因为它是可选的序列化功能,而Gecko只是呈现XSLT结果树,它不会将其序列化。

使用XSLT 2.0,因为不使用exsl:node-set会更容易,请参阅http://xsltransform.net/nc4NzRb

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:template name="box2">
  <xsl:param name="fragment"/>
  <div class="panel1">
    <xsl:apply-templates select="$fragment/node()" mode="doe"/>
  </div>
</xsl:template>

<xsl:template match="text()" mode="doe">
    <xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

<xsl:template match="*" mode="doe">
    <xsl:copy-of select="."/>
</xsl:template>

<xsl:template match="/">
    <xsl:call-template name="box2">
      <xsl:with-param name="fragment">
      &lt;b&gt;First&lt;/b&gt;
      <b>Second</b>
      </xsl:with-param>
    </xsl:call-template>
</xsl:template>


</xsl:transform>

在您的评论中,您为输入添加了更多复杂性,如果您想使用相同的方法,那么您不能简单地获取元素节点的深层副本,您需要采用浅层副本并处理子节点同样的方式:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="@* | node()">
    <xsl:for-each select="//root/cmnt">
      <xsl:call-template name="box1">
        <xsl:with-param name="rtf">
          <b>
            <xsl:value-of select="." />
          </b>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="box1">
    <xsl:param name="rtf"/>
    <div>
      <xsl:apply-templates select="msxsl:node-set($rtf)/node()" mode="doe"/>
    </div>
  </xsl:template>
  <xsl:template match="text()" mode="doe">
    <xsl:value-of select="." disable-output-escaping="yes"/>
  </xsl:template>
  <xsl:template match="*" mode="doe">
    <xsl:copy>
      <xsl:apply-templates mode="doe"/>
    </xsl:copy>

  </xsl:template>
</xsl:stylesheet>