twfurst
twfurst

Reputation: 263

XSL-FO Paragraph Numbering in Link

I am generating PDFs of S1000D xml and need to display a link to another step, giving that steps number/letter designation. In the below image what currently shows as a link to 1.d. should read 1.c.

Current output

The source xml containing the ref is as follows:

<mainProcedure>
<proceduralStep id="S0001">
    <para id="P0001">REMOVE COMPONENT XYZ.</para>
    <proceduralStep id="S0002">
        <para id="P0002">This is a second level procedural step.</para>
        <proceduralStep id="S0003">
            <para id="P0003">This is a third level procedural step.</para>
            <proceduralStep id="S0004">
                <para id="P0004">This is a fourth level procedural step.</para>
                <proceduralStep id="S0006">
                    <para id="P0006">This is a fifth level procedural step.</para>
                </proceduralStep>
            </proceduralStep>
        </proceduralStep>
    </proceduralStep>
    <proceduralStep id="S0005">
        <para id="P0005">This is a second, second level procedural step.</para>
    </proceduralStep>
    <proceduralStep id="S0008">
        <para id="P0008">The following sub-step has quantity data included.</para>
        <proceduralStep id="S0009">
            <para>Position bracket on frame and secure with bolts and washers. <emphasis
>TORQUE BOLT TO <quantity>
                        <quantityGroup quantityGroupType="minimum"
quantityUnitOfMeasure="ft.lbf">
                            <quantityValue>10</quantityValue>
                        </quantityGroup>
                        <quantityGroup quantityGroupType="maximum"
quantityUnitOfMeasure="ft.lbf">
                            <quantityValue>15</quantityValue>
                        </quantityGroup>
                    </quantity>
                </emphasis>.</para>
        </proceduralStep>
    </proceduralStep>
    <proceduralStep id="S0007">
        <para id="P0007">This is a para with a reference to <internalRef
internalRefId="S0008" internalRefTargetType="step"> another step</internalRef
> in the procedure.</para>
    </proceduralStep>
</proceduralStep>

Here is the XSL I have that gives me the incorrect number/letter combo. It appears to be giving me the number for the step that contains the link (there is another template that handles the <quantity> data:

<xsl:template match="internalRef[@internalRefTargetType='step']">
        <xsl:variable name="refId" select="./@internalRefId"/>
        <xsl:if test="//mainProcedure//proceduralStep/@id = $refId">
            <xsl:if test="//mainProcedure/proceduralStep/@id = $refId">
                <fo:inline>
                    <fo:basic-link internal-destination="{$refId}" color="blue" text-decoration="underline">
                        Step <xsl:number level="multiple" count="mainProcedure/proceduralStep" format="1."/>
                    </fo:basic-link>
                </fo:inline>
            </xsl:if>
            <xsl:if test="//mainProcedure/proceduralStep/proceduralStep/@id = $refId">
                <fo:inline>
                    <fo:basic-link internal-destination="{$refId}" color="blue" text-decoration="underline">
                        Step <xsl:number level="multiple" count="//mainProcedure/proceduralStep" format="1."/><xsl:number level="single" count="//mainProcedure/proceduralStep | proceduralStep" format="a."/>
                    </fo:basic-link>
                </fo:inline>
            </xsl:if>
        </xsl:if>
    </xsl:template>

Any help getting me on the correct path is much appreciated.

Upvotes: 1

Views: 502

Answers (1)

Daniel Haley
Daniel Haley

Reputation: 52888

I think you're making xsl:number too complicated. You should be able to use just one xsl:number and eliminate the xsl:if's (by doing an xsl:apply-templates and using a moded template).

However, I've run into issues with parens in the format attribute, so you might have to do some additional formatting to the resulting number. Also, you'd have to add an fo:inline to underline the number for the 5th level step in the reference, but since the entire link is underlined anyway you'd never see it.

Here's an example of what I was thinking. This only handles the references and is for illustration purposes only.

XML Input (added additional references at the bottom)

<mainProcedure>
    <proceduralStep id="S0001">
        <para id="P0001">REMOVE COMPONENT XYZ.</para>
        <proceduralStep id="S0002">
            <para id="P0002">This is a second level procedural step.</para>
            <proceduralStep id="S0003">
                <para id="P0003">This is a third level procedural step.</para>
                <proceduralStep id="S0004">
                    <para id="P0004">This is a fourth level procedural step.</para>
                    <proceduralStep id="S0006">
                        <para id="P0006">This is a fifth level procedural step.</para>
                    </proceduralStep>
                </proceduralStep>
            </proceduralStep>
        </proceduralStep>
        <proceduralStep id="S0005">
            <para id="P0005">This is a second, second level procedural step.</para>
        </proceduralStep>
        <proceduralStep id="S0008">
            <para id="P0008">The following sub-step has quantity data included.</para>
            <proceduralStep id="S0009">
                <para>Position bracket on frame and secure with bolts and washers. <emphasis
                    >TORQUE BOLT TO <quantity>
                        <quantityGroup quantityGroupType="minimum"
                            quantityUnitOfMeasure="ft.lbf">
                            <quantityValue>10</quantityValue>
                        </quantityGroup>
                        <quantityGroup quantityGroupType="maximum"
                            quantityUnitOfMeasure="ft.lbf">
                            <quantityValue>15</quantityValue>
                        </quantityGroup>
                    </quantity>
                </emphasis>.</para>
            </proceduralStep>
        </proceduralStep>
        <proceduralStep id="S0007">
            <para id="P0007">This is a para with a reference to <internalRef
                internalRefId="S0008" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>
            <para>This is a para with a reference to <internalRef
                internalRefId="S0001" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>
            <para>This is a para with a reference to <internalRef
                internalRefId="S0002" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>
            <para>This is a para with a reference to <internalRef
                internalRefId="S0003" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>
            <para>This is a para with a reference to <internalRef
                internalRefId="S0004" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>
            <para>This is a para with a reference to <internalRef
                internalRefId="S0005" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>
            <para>This is a para with a reference to <internalRef
                internalRefId="S0006" internalRefTargetType="step"> another step</internalRef
                > in the procedure.</para>

        </proceduralStep>
    </proceduralStep>
</mainProcedure>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="internalRef[@internalRefTargetType='step']">
        <xsl:variable name="refId" select="@internalRefId"/>
        <fo:inline>
            <fo:basic-link internal-destination="{$refId}" color="blue" 
                text-decoration="underline">
                <xsl:text>Step </xsl:text> 
                <xsl:apply-templates select="//proceduralStep[@id=$refId]" mode="nbr"/>
            </fo:basic-link>
        </fo:inline>    
    </xsl:template>

    <xsl:template match="proceduralStep" mode="nbr">
        <xsl:variable name="origNbr">
            <xsl:number level="multiple" format="1.a.1.a.1"/>            
        </xsl:variable>
        <xsl:for-each select="tokenize($origNbr,'\.')">
            <xsl:value-of select="if (position()=(3,4)) then concat('(',.,')') 
                else if (position()=5) then . else concat(.,'.')"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

XML Output

<mainProcedure>
   <proceduralStep id="S0001">
      <para id="P0001">REMOVE COMPONENT XYZ.</para>
      <proceduralStep id="S0002">
         <para id="P0002">This is a second level procedural step.</para>
         <proceduralStep id="S0003">
            <para id="P0003">This is a third level procedural step.</para>
            <proceduralStep id="S0004">
               <para id="P0004">This is a fourth level procedural step.</para>
               <proceduralStep id="S0006">
                  <para id="P0006">This is a fifth level procedural step.</para>
               </proceduralStep>
            </proceduralStep>
         </proceduralStep>
      </proceduralStep>
      <proceduralStep id="S0005">
         <para id="P0005">This is a second, second level procedural step.</para>
      </proceduralStep>
      <proceduralStep id="S0008">
         <para id="P0008">The following sub-step has quantity data included.</para>
         <proceduralStep id="S0009">
            <para>Position bracket on frame and secure with bolts and washers. <emphasis>TORQUE BOLT TO <quantity>
                     <quantityGroup quantityGroupType="minimum" quantityUnitOfMeasure="ft.lbf">
                        <quantityValue>10</quantityValue>
                     </quantityGroup>
                     <quantityGroup quantityGroupType="maximum" quantityUnitOfMeasure="ft.lbf">
                        <quantityValue>15</quantityValue>
                     </quantityGroup>
                  </quantity>
               </emphasis>.</para>
         </proceduralStep>
      </proceduralStep>
      <proceduralStep id="S0007">
         <para id="P0007">This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0008"
                              color="blue"
                              text-decoration="underline">Step 1.c.</fo:basic-link>
            </fo:inline> in the procedure.</para>
         <para>This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0001"
                              color="blue"
                              text-decoration="underline">Step 1.</fo:basic-link>
            </fo:inline> in the procedure.</para>
         <para>This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0002"
                              color="blue"
                              text-decoration="underline">Step 1.a.</fo:basic-link>
            </fo:inline> in the procedure.</para>
         <para>This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0003"
                              color="blue"
                              text-decoration="underline">Step 1.a.(1)</fo:basic-link>
            </fo:inline> in the procedure.</para>
         <para>This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0004"
                              color="blue"
                              text-decoration="underline">Step 1.a.(1)(a)</fo:basic-link>
            </fo:inline> in the procedure.</para>
         <para>This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0005"
                              color="blue"
                              text-decoration="underline">Step 1.b.</fo:basic-link>
            </fo:inline> in the procedure.</para>
         <para>This is a para with a reference to <fo:inline xmlns:fo="http://www.w3.org/1999/XSL/Format">
               <fo:basic-link internal-destination="S0006"
                              color="blue"
                              text-decoration="underline">Step 1.a.(1)(a)1</fo:basic-link>
            </fo:inline> in the procedure.</para>
      </proceduralStep>
   </proceduralStep>
</mainProcedure>

Upvotes: 2

Related Questions