代码之家  ›  专栏  ›  技术社区  ›  Ilya

xslt模板优化

  •  2
  • Ilya  · 技术社区  · 16 年前

    我有以下xslt代码:

    <xsl:template match="table_terms_and_abbr">
        <informaltable frame='none' colsep='none' rowsep='none'>
            <tgroup cols='2' align='left'>
                <colspec colnum="1" colwidth='1*'/>
                <colspec colnum="2" colwidth='1*'/>
                <xsl:apply-templates/>
            </tgroup>     
        </informaltable>
    </xsl:template>
    

    以及它正在处理的以下XML:

    <table_terms_and_abbr>
            <tblrow_hdr>Name ,, Description</tblrow_hdr>
            <tbody>
                <tblrow_bold_first> BOT ,, &j_bot;</tblrow_bold_first>
                ...
            </tbody>    
    </table_terms_and_abbr>
    

    现在我想通过在 table_terms_and_abbr :

    <tblrow_hdr>Name ,, Description</tblrow_hdr>
    <tbody>
    
    </tbody>
    

    所以我要一些东西:

    <xsl:template match="table_terms_and_abbr">
        <informaltable frame='none' colsep='none' rowsep='none'>
            <tgroup cols='2' align='left'>
                <colspec colnum="1" colwidth='1*'/>
                <colspec colnum="2" colwidth='1*'/>
                 <xsl:call-template name="tblrow_hdr">
                      BOT ,, &j_bot;                      * ???? *
                 </xsl:call-template>
                <tbody>
                <xsl:apply-templates/>
                </tbody>
            </tgroup>     
        </informaltable>
    </xsl:template>
    

    标有*的那一行?????*不起作用。我在linux平台上使用saxon9(xslt 2.0样式表),得到以下错误:

    xtse0010:xsl:call模板中不允许有字符数据

    我知道如何将属性传递给模板,即:

    <xsl:with-param name="is_make_first_bold" select = "1" as="xs:integer"/>
    

    但是如何传递自由文本呢?

    其思想是将所有静态数据移到模板中,并且在xml中只使用变量数据,即

    <table_terms_and_abbr>
        <tblrow_bold_first> BOT ,, &j_bot;</tblrow_bold_first>
        ...
    </table_terms_and_abbr>
    

    更多信息
    我的要求是创建一个简化的语法来为docbook文档定义可重复的表。为此,我创建了一个名为template的通用模板 tblrow 这将拆分由“,,”分隔的行以分隔实体,并将在表行中创建条目列表。
    每个条目可以是简单的字符串、实体或其他模板。 由于参数编号是未定义的(表可以有不同数量的单元格),因此我不能为模板使用标准参数,也不能使用分隔字符串。如果要使其中一个表条目包含指向文档中某个位置的链接,则不能再次使用这些参数,因为不能将外部参照模板作为参数传递。
    不改变的主要原因 丁苯橡胶 模板是它在工作:)而且有点复杂。我花了很长时间才做到这一点,我不完全理解它是如何工作的:)。

    除此之外,我还有几个变量可以控制显示的输出,比如 tblrow_hdr 将在每个条目中的文本加下划线和粗体。自从 TBLROWH-HDR 是所有人的共同点 表四术语 表对我来说这听起来很合理,没有XML格式,而是调用 TBLROWH-HDR 里面 表四术语 模板和这里我坚持。

    3 回复  |  直到 16 年前
        1
  •  3
  •   ddaa    16 年前

    我知道如何将属性传递给模板,即:

    <xsl:with-param name="is_make_first_bold" select = "1" as="xs:integer"/>
    

    但是如何传递自由文本呢?

    将文本作为 xsl:with-param 元素。

    XSL Transformations 11.6 Passing Parameters to Templates

    <xsl:with-param
      name = qname
      select = expression>
      <!-- Content: template -->
    </xsl:with-param>
    

    参数使用 xsl:with参数 元素。所需 name 属性指定参数的名称(要替换其绑定值的变量)。name属性的值是 QName ,按中所述展开 [2.4 Qualified Names] . '两者中都允许xsl:with param' xsl:call-template xsl:apply-templates . 参数值的指定方式与 xsl:variable xsl:param . 用于计算由指定的值的当前节点和当前节点列表 xsl:with参数 元素与用于 xsl:apply模板 xsl:call模板 在其中发生的元素。传递参数不是错误 X 对于没有 PARAM 元素用于 X ;参数被忽略。

    此示例为带参数的编号块定义命名模板,以控制编号的格式。

    <xsl:template name="numbered-block">
      <xsl:param name="format">1. </xsl:param>
      <fo:block>
        <xsl:number format="{$format}"/>
        <xsl:apply-templates/>
      </fo:block>
    

    <xsl:template match="ol//ol/li">
      <xsl:call-template name="numbered-block">
        <xsl:with-param name="format">a. </xsl:with-param>
      </xsl:call-template>
    </xsl:template>
    
        2
  •  1
  •   Dimitre Novatchev    16 年前

    可以将其他字符串数据作为参数传递:

    <xsl:with param name=“pneededtext”选择“'--123abc'”/>

    在调用的模板中定义此参数:

    <xsl:param name=“pneededtext”as=“xs:string”>

    或者,你可以定义 全球的 <xsl:variable/> <xsl:param/> 并直接在调用的模板中引用它。

        3
  •  1
  •   Dimitre Novatchev    16 年前
    > Since the parameter numbers are
    > undefined (the tables can have
    > different number of cells) i can't use
    > a standard parameters for the
    > templates and used delimited string.

    实际上,情况并非如此。

    下面是一个

    <xsl:with-param/>
    ,其主体是一个节点集,该节点集可以由不同调用上的不同数量的元素组成:
        <xsl:template match="/">
          <xsl:variable name="vrtfTParams">
            <p>xxx</p>
            <p>yyy</p>
            <p>zzz</p>
          </xsl:variable>
    
          <xsl:call-template name="makeTable">
            <xsl:with-param name="pTParams"
             select="msxsl:node-set($vrtfTParams)/*"/>
          </xsl:call-template>
        </xsl:template>
    

    “maketable”模板可以如此简单:

        <xsl:template name="makeTable">
          <xsl:param name="pTParams"/>
    
          <table>
            <tr>
              <xsl:for-each select="$pTParams">
                <td>
                  <xsl:value-of select="."/>
                </td>
              </xsl:for-each>
            </tr>
          </table>
        </xsl:template>
    

    msxsl:node-set()扩展函数可用于Microsoft xslt处理器。大多数其他处理器都支持exslt:node-set()扩展函数(Microsoft的.NET xslt处理器xslcompiledtransform也支持它)。

    如果$vrtftparams的内容不是动态生成的(与本例中的情况一样),则不需要xxx:node-set()函数,因为可以这样传递<xsl:variable>的内容:

     <xsl:with-param name="pTParams"
       select="document('')/*/xsl:variable[name()=vrtfTParams)/*"/>
    

    这里必须全局定义$vrtftparams(xsl:template/>的子级)。

    在xslt 2.0(和xpath2.0)中,没有rtf类型,根本不需要xxx:node-set()扩展函数。

    希望这有帮助。

    干杯,

    迪米特里诺瓦切夫