使用FO:LIST-BLOCK生成PDF时,正确对齐XML数据



我在XML输入中有数字列表,我能够对准列表主体(文本内容)以对准正确,但是数字仍然与左对齐。我如何对齐整个列表,包括右数字/子弹,默认情况下是剩下的。非常感谢任何帮助或指针。

当前输出:

 Number list below
 1.                                                                 L List 1
 2.                                                                 R list 2

我的预期输出:

 Number list below
                                                                   1. L List 1
                                                                   2. R list 2

我已经简化了XML数据:

<p>Number list below</p>
      <ol>
         <li style="text-align: right;">L list 1</li>
         <li style="text-align: right;">R list 2</li>
      </ol>

我的XSLT代码看起来如下:

<xsl:template match="LI|li">
	<fo:list-block>	
		<xsl:attribute name="text-align">
			<!--xsl:value-of select="end"/-->
			<xsl:text disable-output-escaping="yes">right</xsl:text>
		</xsl:attribute>		
		<fo:list-item>
			<fo:list-item-label end-indent="label-end()">
				<fo:block>
					<xsl:variable name="value-fetcher">
						<xsl:choose>
							<xsl:when test="../@start">
								<xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI)+ ../@start"/>
							</xsl:when>
							<xsl:otherwise>
								<xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI) + 1"/>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:variable>
					<xsl:number value="$value-fetcher" format="1."/>					
				</fo:block>
			</fo:list-item-label>
			<fo:list-item-body start-indent="body-start()">			
				<fo:block>
					<xsl:apply-templates select="text()"/>
				</fo:block>
			</fo:list-item-body>				
		</fo:list-item>
	</fo:list-block>
</xsl:template>

在我看来,右键,可变的宽度列表并不是fo:list-block设计的。

假设您的Fo Formatter实现fo:table-and-caption,您可以制作一个看起来像您想要的表:

  <table-and-caption text-align="right">
    <table text-align="left">
      <table-body>
        <table-row>
          <table-cell padding="1pt">
            <block>1.</block>
          </table-cell>
          <table-cell padding="1pt">
            <block>L List 1</block>
          </table-cell>
        </table-row>
      </table-body>
      <table-body>
        <table-row>
          <table-cell padding="1pt">
            <block>2.</block>
          </table-cell>
          <table-cell padding="1pt">
            <block>R list 2</block>
          </table-cell>
        </table-row>
      </table-body>
    </table>
  </table-and-caption>

在没有fo:table-and-caption的情况下,您可以滥用fo:block-containerwriting-mode属性:

  <block-container writing-mode="rl">
    <table text-align="left" writing-mode="lr">

或者您可以使用 fo:leader(https://www.w3.org/tr/xsl11/#fo_leader)来'推' fo:inline-container(https://www.w.org/www.org/tr/xsl/xsl/xsl11/#fo_inline-inline-inline-line-inline-line-inline-line-inline-inline-inline-inline-inline-inline-inline-inline-inline-inline-inline-in,,,,,,,,右侧的容器):

  <block>
    <leader leader-length.optimum="100%"/><inline-container>
    <table>

模板有一些问题:

  • 您没有设置provisional-distance-between-starts,其中与provisional-label-separation一起确定了项目标签的宽度,因此您将获得24pt -6pt = 18pt
  • 的宽度
  • 您的物品标签没有所需的end-indent="label-end()",并且物品的身体缺少start-indent="body-start()",因此它们的尺寸不正确/定位。

此修订的模板应起作用:

<xsl:template match="LI|li">
    <fo:list-block text-align="end" provisional-distance-between-starts="3cm"><!-- set the value you want! -->  
        <fo:list-item>
            <fo:list-item-label end-indent="label-end()">
                <fo:block>
                    <xsl:variable name="value-fetcher">
                        <xsl:choose>
                            <xsl:when test="../@start">
                                <xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI)+ ../@start"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI) + 1"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    <xsl:number value="$value-fetcher" format="1."/>                    
                </fo:block>
            </fo:list-item-label>
            <fo:list-item-body start-indent="body-start()">         
                <fo:block>
                    <xsl:apply-templates select="text()"/>
                </fo:block>
            </fo:list-item-body>                
        </fo:list-item>
    </fo:list-block>
</xsl:template>

只是一个次要的nitpick:您正在为输入中的每个li元素创建一个fo:list-block,而您可以为每个olul创建一个。


您不知道要保留标签的宽度,但这取决于项目本身...嗯,也许您根本不需要使用fo:list-block

右对齐的fo:block应该足够了,只要项目文本总是创建一行:

<xsl:template match="LI|li">
    <fo:block text-align="end"> 
        <fo:inline>
            <xsl:variable name="value-fetcher">
                <xsl:choose>
                    <xsl:when test="../@start">
                        <xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI)+ ../@start"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI) + 1"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:number value="$value-fetcher" format="1."/>                    
        </fo:inline> 
        <fo:inline>
            <xsl:apply-templates select="text()"/>
        </fo:inline>
    </fo:block>
</xsl:template>

感谢您的答复,总是有用的。

xslt下方实现的对齐:

<xsl:template match="LI|li">
<fo:block margin-left="36pt" text-align="right">
	<fo:leader leader-pattern="space" leader-length="-18pt"/>
	<fo:inline><xsl:variable name="value-fetcher">
                        <xsl:choose>
                            <xsl:when test="../@start">
                                <xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI)+ ../@start"/>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:number value="count(preceding-sibling::li) + count(preceding-sibling::LI) + 1"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    <xsl:number value="$value-fetcher" format="1."/> 
	</fo:inline>
	<fo:inline>
	<fo:leader leader-pattern="space" leader-length="18pt"/>
	 <xsl:apply-templates select="text()"/>
	</fo:inline>
</fo:block>
</xsl:template>

最新更新