简体   繁体   English

xsl:number 问题以计算元素 XSLT 3.0 XSL-FO

[英]Issue with xsl:number to count elements XSLT 3.0 XSL-FO

I'm trying to number the <para>s , there is only one <para> per crewDrillStep but we can have nested crewDrillStep s.我正在尝试对<para>s进行编号,每个crewDrillStep只有一个<para>但我们可以嵌套crewDrillStep It works as expected unless there is an <if> block, then the numbering restarts.它按预期工作,除非有一个<if>块,然后重新开始编号。 If I remove the <if> then it numbers correctly.如果我删除<if>那么它的编号是正确的。

I updated the example with Martin's suggestion which is so close, but there could be more than one crewDrill and I noticed in some instances the numbering of the second level para wasn't restarting.我用 Martin 的建议更新了这个例子,这个建议非常接近,但可能有不止一个crewDrill ,我注意到在某些情况下,第二级para的编号没有重新开始。 Also there are some paras with bullets in the xml which aren't to be numbered. xml 中还有一些带子弹的段位,不进行编号。

Given:鉴于:

<crew>
    <crewRefCard>
        <title>Expanded Self-Test Procedures </title>
        <crewDrill>
           <if>
              <caseCond>After program stops at test No. 1:</caseCond>
              <crewDrillStep id="d1e21189">
                 <para>RESET switch - ELEC.</para>
              </crewDrillStep>
              <crewDrillStep id="d1e21195">
                 <para>Flip red switches:</para>
                 <crewDrillStep id="d1e21200">
                    <para>Right.</para>
                 </crewDrillStep>
                 <crewDrillStep id="d1e21206">
                    <para>Left.</para>
                 </crewDrillStep>
                 <crewDrillStep id="d1e21212">
                    <para>Rudder.</para>
                 </crewDrillStep>
              </crewDrillStep>
              <crewDrillStep id="d1e21219">
                 <para>Flip orange switch.</para>
                 <crewDrillStep id="d1e21224">
                    <para>Test No. advances to 2.</para>
                 </crewDrillStep>
                 <crewDrillStep id="d1e21230">
                    <para>Yellow caution light - On.</para>
                 </crewDrillStep>
                 <crewDrillStep id="d1e21236">
                    <para>Red warning light - On.</para>
                 </crewDrillStep>
                 <crewDrillStep id="d1e21242">
                    <para>Program stops.</para>
                 </crewDrillStep>
              </crewDrillStep>
        </crewDrill>
    </crewRefCard>
</crew>

and:和:

<xsl:template name="para" match="para | notePara | warningAndCautionPara | attentionListItemPara">
    <fo:block text-align="justify">           
        <xsl:choose>
            <xsl:when test="self::para and (parent::crewDrillStep)">
                <fo:block>
                    <xsl:choose>
                        <xsl:when test="count(ancestor::crewDrillStep)=1">
                            <xsl:number from="crewDrill" level="any" count="crewDrillStep"/>
                        </xsl:when>
                        <xsl:when test="count(ancestor::crewDrillStep)=2 ">     
                            <xsl:attribute name="margin-left" select="'.25in'"/>
                            <xsl:number from="crewDrill/crewDrillStep" level="any" count="para[count(ancestor::crewDrillStep) = 2][not(starts-with(normalize-space(.),'•'))]" format="a. "/>
                        </xsl:when>
                        <xsl:when test="count(ancestor::crewDrillStep)=3">
                            <xsl:attribute name="margin-left" select="'.50in'"/>
                            <xsl:number from="crewDrill" count="crewDrillStep" format="(1) "/> 
                        </xsl:when>
                        <xsl:otherwise/>
                    </xsl:choose>
                </fo:block>
                <fo:block>
                    <xsl:apply-templates select="node()" mode="include"/>
                </fo:block>
            </xsl:when>
        </xsl:choose>
    </fo:block>
</xsl:template>

Desired output:所需的 output:

Expanded Self-Test Procedures
After program stops at test No. 1:
1. RESET switch - ELEC.
2. Flip red switches:
    a. Right
    b. Left.
    c. Rudder.
3. Flip orange switch.
    a. Test No. advances to 2.
    b. Yellow caution light - On.
    c. Red warning light - On.
    d. Program stops.

Actual output:实际 output:

Expanded Self-Test Procedures
After program stops at test No. 1:
1. RESET switch - ELEC.
2. Flip red switches:
    a. Right
    b. Left.
    c. Rudder.
3. Flip orange switch.
    d. Test No. advances to 2.
    e. Yellow caution light - On.
    f. Red warning light - On.
    g. Program stops.

If I understand your intention right, then doing如果我理解你的意图是正确的,那么做

                      <xsl:when test="count(ancestor::crewDrillStep)=2 ">     
                          <xsl:attribute name="margin-left" select="'.25in'"/>
                          <xsl:number from="crewDrill/crewDrillStep" level="any" count="para[count(ancestor::crewDrillStep) = 2]" format="a. "/>
                      </xsl:when>

instead of代替

                    <xsl:when test="count(ancestor::crewDrillStep)=2 ">     
                        <xsl:attribute name="margin-left" select="'.25in'"/>
                        <xsl:number from="crewDrill" count="crewDrillStep" format="a. "/>
                    </xsl:when>

should give the wanted numbering for those second level para s.应该为那些二级para s 提供所需的编号。

As an alternative to use the use of xsl:number , one could define and use an accumulator:作为使用xsl:number的替代方法,可以定义和使用累加器:

  <xsl:accumulator name="para-count-seq" as="xs:integer*" initial-value="()">
    <xsl:accumulator-rule match="crewDrill" select="0"/>
    <xsl:accumulator-rule match="crewDrill" phase="end" select="()"/>
    <xsl:accumulator-rule match="crewDrillStep" select="$value, 0"/>
    <xsl:accumulator-rule match="crewDrillStep" phase="end" select="$value[position() lt last()]"/>
    <xsl:accumulator-rule match="para" 
        select="let $pos := count(ancestor::crewDrillStep)
                return ($value[position() lt $pos], $value[$pos] + 1, $value[position() gt $pos])"/>
  </xsl:accumulator>

  <xsl:mode use-accumulators="para-count-seq"/>

and then output the number for each para with eg然后是 output 每个para的编号,例如

  <xsl:template match="para">
    <xsl:number 
        value="accumulator-before('para-count-seq')[last() - 1]" 
        format="{('1. ', 'a. ', '(1)')[count(current()/ancestor::crewDrillStep)]}"/>
  </xsl:template>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM