使用XSLT独立插入打开和关闭HTML标记

sem*_*d3r 1 html tags xslt variables

我习惯了以下变量:

<xsl:variable name="openTag">
<![CDATA[
<div>
]]>
</xsl:variable>

<xsl:variable name="closeTag">
<![CDATA[
</div>
]]>
</xsl:variable>
Run Code Online (Sandbox Code Playgroud)

并按以下方式实施:

<div class="root">
      <xsl:variable name="ownerid" select="Prp[@name='owner id']/@value" />
      <xsl:variable name="nextownerid" select="preceding-sibling::Node[1]/Prp[@name='owner id']/@value"/>

      <xsl:choose>
        <xsl:when test="$ownerid = '-1'">
          <xsl:copy-of select="$LogText"/>
        </xsl:when>
        <xsl:when test="$ownerid &lt; $nextownerid">
          <xsl:copy-of select="$openTag"/>
          <xsl:copy-of select="$LogText"/>
        </xsl:when>

        <xsl:when test="$ownerid &gt; $nextownerid">
          <xsl:copy-of select="$openTag"/>
          <xsl:copy-of select="$LogText"/>
          <xsl:copy-of select="$closeTag"/>
          <xsl:copy-of select="$closeTag"/>
        </xsl:when>

        <xsl:otherwise>
          <xsl:copy-of select="$openTag"/>
          <xsl:copy-of select="$LogText"/>
          <xsl:copy-of select="$closeTag"/>
        </xsl:otherwise>
      </xsl:choose>
    </div>
Run Code Online (Sandbox Code Playgroud)

问题是div标签作为文本输出而不被识别为HTML标签.有没有解决方法?

Mic*_*Kay 8

XSLT是一种树转换语言:它将节点树作为输入,并生成节点树作为输出.它不读取包含开始和结束标记的词法XML,也不输出包含开始和结束标记的词法XML.输入树(通常)由词汇XML由称为XML解析器的单独处理器构造,输出树(通常)由称为XML序列化器的单独处理器转换为词汇XML.

disable-output-escaping是一种破解,XSLT处理器将带外信息发送给串行器.因此,它会在变换器和串行器之间产生不希望的紧密耦合,这会阻止您的XSLT代码在没有序列化器的管道中工作(例如,Firefox).

看起来您的逻辑正在尝试解决"群组相邻"问题:将具有相同所有者ID的所有相邻元素分组.在不使用序列化黑客的情况下,有更好的方法可以解决XSLT中的问题.在XSLT 2.0中:

<xsl:for-each-group select="*" group-adjacent="owner-id">
  <div>
    <xsl:copy-of select="current-group()"/>
  </div>
</xsl:for-each-group>
Run Code Online (Sandbox Code Playgroud)

如果你受限于XSLT 1.0,这有点棘手,但并不难:寻找"兄弟递归"的例子.