缩进xsl:text的多行块

时间:2014-07-01 14:50:22

标签: xslt

是否有一种简单的方法可以在XSL中缩进整个文本块?我希望缩进文本块以大致匹配XML的嵌套级别。

答案在这里XSL: output of "nested" structures 提出一个缩进参数,当你递归时它会增加。

这是一个好的开始,但需要很长的< value-of>标记在每行的开头,当然不能放在< xsl:text>的内部。块。

那么,有没有办法用它来缩进多行< xsl:text>块?我不想将每一行分别包装成< xsl:text>块,只是为了我可以在每行的开头添加一个变量。

示例模板:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="drv">
    <xsl:param name="pIndent"/>

    <xsl:text>
Column {
    anchors { left: parent.left; right: parent.right }
    </xsl:text>
    <xsl:apply-templates select="snc|kap">
         <xsl:with-param name="pIndent" select="concat($pIndent, '    ')"/>
    </xsl:apply-templates>
    <xsl:text>
}</xsl:text>

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

所以,我希望能够在appriate缩进级别输出文本。那么,有没有办法动态缩进整个&lt; xsl:text&gt;块(或在这种情况下块)?这将允许输出代码正确缩进,使我更容易调试。

像这样输出,但缩进到周围代码中的正确级别:

Column {
    anchors { left: parent.left; right: parent.right }

    [Code from some other template
    kept at this indent level]
}

我会尝试用几种不同的方式总结这个问题,因为人们正在努力理解它:

给定运行时已知的缩进级别,如何缩进整个&lt; xsl:text&gt;的内容?阻止到那个级别?

或者可选:给定运行时已知的值,如何将值预先添加到&lt; xsl:text&gt;中每行的开头?方框?

1 个答案:

答案 0 :(得分:0)

你基本上想要一个&#34;功能&#34;可以使用字符串并将特定前缀添加到字符串的开头,也可以在字符串包含的每个换行符后立即添加。在XSLT 2.0中,使用正则表达式replace函数非常简单,但不幸的是lxml只支持XSLT 1.0。

在XSLT 1.0中,我使用尾递归命名模板来解决这个问题:

<xsl:template name="printIndented">
  <xsl:param name="text" />
  <xsl:param name="indent" />

  <xsl:if test="$text">
    <xsl:value-of select="$indent" />
    <xsl:variable name="thisLine" select="substring-before($text, '&#10;')" />
    <xsl:choose>
      <xsl:when test="$thisLine"><!-- $text contains at least one newline -->
        <!-- print this line -->
        <xsl:value-of select="concat($thisLine, '&#10;')" />
        <!-- and recurse to process the rest -->
        <xsl:call-template name="printIndented">
          <xsl:with-param name="text" select="substring-after($text, '&#10;')" />
          <xsl:with-param name="indent" select="$indent" />
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>

使用&#34;功能&#34;你必须做像

这样的事情
<xsl:call-template name="printIndented">
  <xsl:with-param name="indent" select="$pIndent" />
  <xsl:with-param name="text"
>Column {
    anchors { left: parent.left; right: parent.right }</xsl:with-param>
</xsl:call-template>

<xsl:apply-templates select="snc|kap">
  <xsl:with-param name="pIndent" select="concat($pIndent, '    ')"/>
</xsl:apply-templates>

<xsl:call-template name="printIndented">
  <xsl:with-param name="indent" select="$pIndent" />
  <xsl:with-param name="text">}</xsl:with-param>
</xsl:call-template>

当然,您必须非常小心,不要在XSLT源代码本身上使用自动格式化程序,因为这会将所有精心缩进的代码抛出窗口...