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

xslt 3.0参数未被覆盖

  •  0
  • Caroline  · 技术社区  · 2 年前

    鉴于

    <table>
      <title>Inspection</title>
      <tgroup/>
         <tbody>
           <row>
           <entry>
              <para>Blend well.</para>
           </entry>
           </row>
           <row>
               <entry>
                  <effect effrg="cde"/>
               </entry>
            </row>
            <!-- this entry would be empty -->
           <row>
               <entry>
                  <effect effrg="cde"/>
               </entry>
            </row>
           <row>
               <entry>
               <!-- first effect would create a block, second should be ignored -->
                  <effect effrg="abc"/>
                  <effect effrg="abc"/>
               </entry>
            </row>
        </tbody>
    </table>
    

    我试图防止由空引起的错误 fo:table-cell 。当的独生子女 <entry> <effect> ,以及 effect/@effrg 与以前匹配 @effrg ,因为那样就不会打印任何内容。我想尽量减少无关的事情 fo:blocks 所以我想我可以使用参数作为标志:

    <xsl:template match="entry/effect[not(*)]" priority="50"> 
        <xsl:param name="need-block" as="xs:boolean" select="true()"/>
        
        <xsl:variable name="preceding-effrg" as="xs:string?">
            <xsl:call-template name="get-previous-effectivity"/>
        </xsl:variable>
        
        <xsl:variable name="effrg" as="xs:string?" select="normalize-space(@effrg)"/>
               
        <xsl:choose>
            <xsl:when test="$effrg ne $preceding-effrg">
                <fo:block xsl:use-attribute-sets="effect">
                    <xsl:text>{$asterisks3} </xsl:text>
                    <xsl:apply-templates select="@effrg"/>
                </fo:block>
                <xsl:apply-templates>
                    <xsl:with-param name="need-block"  as="xs:boolean" select="false()" tunnel="true"/>
                </xsl:apply-templates>
            </xsl:when>
            <xsl:when test="$need-block="false()"/>
            <!-- any other sibling elements will create a block -->
            <xsl:when test="../*[local-name() ne 'effect']"/>
            <xsl:when test="following-sibling::*"/> 
            <xsl:otherwise>
                <fo:block/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <xsl:template name="get-previous-effectivity">
            <xsl:param name="pos" as="xs:integer" select="1" />
            <xsl:value-of select="preceding::effect[$pos]/@effrg[normalize-space(.) != ''][1]"/>
        </xsl:template>
    

    我无法更改的值 $need-block 在中 effect 通过将另一个值传递给模板。如果指定了默认值,它将保留该值,如果没有默认值,则保持为空,即使我确认传入的参数为 false() 。我尝试了隧道,关闭了隧道,从父级传递,然后从模板传递 $need块 被默认为 错误的 。当我遍历代码时,它似乎忽略了 $with-param 。我在xslt 1.0中已经这样做了,这被认为是不好的做法吗?

    0 回复  |  直到 2 年前
        1
  •  1
  •   Michael Kay    2 年前

    如果在中将其声明为隧道参数 xsl:with-param 则它将只匹配用声明的参数 tunnel="yes" 在里面 xsl:param ,反之亦然。

        2
  •  0
  •   Martin Honnen    2 年前

    我想知道你是否不能简单地使用累加器。

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="3.0"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:fo="http://www.w3.org/1999/XSL/Format"
      exclude-result-prefixes="#all"
      expand-text="yes">
      
      <xsl:mode use-accumulators="#all"/>
      
      <xsl:param name="asterisks3" as="xs:string">***</xsl:param>
    
      <xsl:accumulator name="last-effrg" as="xs:string?" initial-value="()">
        <xsl:accumulator-rule phase="end" match="effect[@effrg]" select="normalize-space(@effrg)"/>
      </xsl:accumulator>
    
      <xsl:template match="entry/effect[not(*)][not(normalize-space(@effrg) = accumulator-before('last-effrg'))]"> 
          <fo:block>
            <xsl:text>{$asterisks3} </xsl:text>
            <xsl:apply-templates select="@effrg"/>
          </fo:block>
      </xsl:template>  
      
    </xsl:stylesheet>
    

    将输出两个

    <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">*** cde</fo:block>
    ..
    <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">*** abc</fo:block>
    

    我认为您的参数传递失败,因为您在兄弟姐妹中需要参数值,而不是在子代或后代中。