缩进xsl:text的多行块

山姆·布尔

有没有一种简便的方法可以在XSL中缩进整个文本块?我想缩进文本块以大致匹配XML的嵌套级别。

XSL的答案是:“嵌套”结构的输出会提出一个缩进参数,随着递归的增加,该参数会增加。

这是一个很好的开始,但是每行的开头都需要一个长的<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>

因此,我希望能够以适当的缩进级别输出文本。因此,是否有办法动态缩进整个<xsl:text>块(在这种情况下为多个块)?这将使输出代码正确缩进,从而使我更容易调试。

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

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

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

由于人们努力理解该问题,因此我将尝试以几种不同的方式总结该问题:

给定运行时已知的缩进级别,如何将整个<xsl:text>块的内容缩进该级别?

或者,也可以:给定一个在运行时已知的值,如何将该值放在<xsl:text>块中每一行的开头?

伊恩·罗伯茨(Ian Roberts)

本质上,您需要一个“函数”,该函数可以接受字符串,并在字符串的开头以及字符串包含的每个换行符之后紧跟特定的前缀。在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>

要使用“功能”,您必须做类似的事情

<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源代码本身上使用自动格式化程序,因为这会将所有经过仔细缩进的代码从窗口中抛出。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章