未覆盖 XSLT 3.0 参数

xslt 3.0 parameters not being overwritten

提问人:Caroline 提问时间:8/26/2023 最后编辑:Caroline 更新时间:8/29/2023 访问量:48

问:

鉴于:

<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@effrgfo: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>

我无法通过向模板传递另一个值来更改模板中的值。如果分配了默认值,它将保留该值,如果没有默认值,则它保持为空,即使我确认传入的参数是 .我尝试了隧道,关闭了隧道,从父级传递它,然后从默认为 .当我单步执行代码时,它似乎忽略了.我已经在 xslt 1.0 中这样做了,这被认为是不好的做法吗?$need-blockeffectfalse()$need-blockfalse()$with-param

XML 参数传递 XSLT-3.0

评论

0赞 Martin Honnen 8/26/2023
我想知道,鉴于您使用 XSLT 3 并且似乎想要检查前面的一些值,您不能只使用累加器来执行此操作,然后在比较中访问累加器值。您还没有真正解释要比较哪些值,并且代码会检查属性,但还会查找一个元素和一个甚至未在输入示例中显示的其他元素 ()。<xsl:variable name="effrg" as="xs:string?" select="normalize-space(@effrg)"/><xsl:value-of select="((preceding::effect[$pos] | preceding::effect/sbeff[$pos])/@effrg)[normalize-space(.) != ''][1]"/>
0赞 Caroline 8/29/2023
我不完全了解如何设置,所以我没有想到使用它们。我从上面的代码中删除了。只有当电流与前一个不匹配时,才会打印它。因此,如果 has only 作为子项,则可能会导致空的表单元格。accumulatorssbeff@effrg@effrgentryeffect

答:

1赞 Michael Kay 8/26/2023 #1

如果将其声明为 in 中的隧道参数,则它只会与 in 声明的参数匹配,反之亦然。xsl:with-paramtunnel="yes"xsl:param

0赞 Martin Honnen 8/26/2023 #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>

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

评论

0赞 Caroline 8/29/2023
我喜欢,但仍然得到空的表格单元格,当是唯一的子项并匹配前面的单元格时。我尝试向累加器添加更多规则:但我无法在不收到模棱两可的匹配警告的情况下重写模板。effectentryeffect/@effrgeffect/@effrg<xsl:accumulator name="last-effrg" as="xs:string?" initial-value="()"> <xsl:accumulator-rule phase="end" match="(sbeff | effect)[@effrg]" select="normalize-space(@effrg)"/> <xsl:accumulator-rule phase="end" match="(sbeff | effect)[@efftext]" select="normalize-space(@efftext)"/> </xsl:accumulator>
0赞 Martin Honnen 8/29/2023
@Caroline,恐怕我根本没有看到任何 XSLT 代码创建,所以很难说出哪里出了问题。此外,如果同时考虑两者以及元素,则最好同时显示具有两者的最小但完整的样本。table-celleffectsbeff
0赞 Caroline 8/29/2023
谢谢马丁,感谢您抽出宝贵时间,我稍后会重新审视并清理它。在 之前创建。table-cellentryentry/effect