Xml 使用FOP修复PDF中一行中单词的位置

Xml 使用FOP修复PDF中一行中单词的位置,xml,xslt,pdf,apache-fop,Xml,Xslt,Pdf,Apache Fop,我正在尝试实现FOP,以便使用XML和XSLT文件输出PDF 我的问题是,我需要确定单词在一行中的位置(但不是通过使用表格),例如: 我有以下xml: <address> <Line1 length="32" noLine="5" col="60" /> <Line2 length="32" noLine="6" col="60">Mr. John Kane</Line2 > <Line3 length="32" n

我正在尝试实现FOP,以便使用XML和XSLT文件输出PDF

我的问题是,我需要确定单词在一行中的位置(但不是通过使用表格),例如:

我有以下xml:

 <address>
    <Line1 length="32" noLine="5" col="60" />
    <Line2 length="32" noLine="6" col="60">Mr. John Kane</Line2 >
    <Line3 length="32" noLine="7" col="60">15 Street Springfield</Line3 >
    <Line4 length="32" noLine="8" col="60" />
    <Line5 length="32" noLine="9" col="60" />
    <Line6 length="6" noLine="10" col="60">75009</Line6 >
    <Line7 length="25" noLine="10" col="67">Freesberg</Line7 >
    <Line8 length="25" noLine="11" col="67">Idaho</Line8 >
  </address>
这是预期的输出,格式为
PDF

                                         Mr. John Kane
                                         15 Street Springfield


                                         75009 Freesberg
                                               Idaho
PDF
(col)中有以下位置:


约翰·凯恩先生
斯普林菲尔德15街
75009弗里斯堡
爱达荷州

任何帮助都将不胜感激。

这有点复杂,但这应该可以:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*" />
  <xsl:output method="text"/>

  <xsl:variable name="sp" select="'                                                                                          '" />

  <xsl:template match="address/*">
    <xsl:variable name="value">
      <xsl:value-of select="." />
      <xsl:if test="following-sibling::*[1]/@noLine = @noLine">
        <xsl:value-of select="$sp" />
      </xsl:if>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="preceding-sibling::*[1]/@noLine = @noLine">
        <xsl:variable name="col" select="preceding-sibling::*[1]/@col + preceding-sibling::*[1]/@length" />
        <xsl:value-of select="concat(substring($sp,1,@col - $col),substring($value,1,@length))" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="preceding-sibling::*"><xsl:text>&#10;</xsl:text></xsl:if>
        <xsl:value-of select="concat(substring($sp,1,@col),substring($value,1,@length))" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>



要使此转换按原样工作,您的
行..
元素必须按
noLine
/
col
顺序排列,因为它基于如何在前一个元素上填充它。如果他们出了毛病,那就大错特错了

sp
变量必须至少包含所需的空格数,即任何
length
col
属性的最大值。这个解决方案不包括一行末尾的空格——实际上,用尾随空格填充每行更容易,这样就可以填充给定的长度,但我认为最好不要这样做

我只在给出的示例中尝试过,如果它对您得到的任何其他输入都不起作用,请告诉我,我会看看是否可以调整它


编辑:我刚刚注意到你需要PDF格式的,对不起。我只是查看了输出,没有注意到格式。希望您可以将其调整为所需的格式(实际上与您已经尝试过的格式非常相似),但如果不是,我建议您手动创建一个表示输出的PDF,并将该PDF的XML添加到您的问题中。

@DimitreNovatchev很简单:我将
xslt
XML
文件传递给FOP,然后它为MES生成
PDF
,直到转换没有预期/想要的输出——这应该是正确的生成的XSL-FO,然后将其馈送到格式化程序。请添加缺少的信息。Mike,对不起,添加的不是XSLT转换的输出,而是FOP的输出。请提供XSLT转换所需的输出。@MikeMyers:这个问题没有错,对我来说很有意义。我有一个想法,我想尝试一下,如果我成功了,我会发布一个答案。不幸的是,不是真的。有一种方法可以编写一个输出给定数量空格的模板,但它会使样式表的长度增加一倍以上。在已知所需的最大长度的情况下,从硬编码的空格字符串中获取子字符串通常要容易得多。不管它的变化有多大,只要它足够长,足以覆盖源XML中任何地方存在的最大长度即可。在这种情况下,我认为足够的空间来覆盖一行的整个宽度应该是足够的。如果有机会,我会添加一个可以用任意长度调用的模板,它通常很有用。
<-----------------60-------------------->
<-----------------60-------------------->Mr. John Kane
<-----------------60-------------------->15 Street Springfield
<-----------------60-------------------->
<-----------------60-------------------->
<-----------------60-------------------->75009 Freesberg
<-----------------67-------------------------->Idaho
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*" />
  <xsl:output method="text"/>

  <xsl:variable name="sp" select="'                                                                                          '" />

  <xsl:template match="address/*">
    <xsl:variable name="value">
      <xsl:value-of select="." />
      <xsl:if test="following-sibling::*[1]/@noLine = @noLine">
        <xsl:value-of select="$sp" />
      </xsl:if>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="preceding-sibling::*[1]/@noLine = @noLine">
        <xsl:variable name="col" select="preceding-sibling::*[1]/@col + preceding-sibling::*[1]/@length" />
        <xsl:value-of select="concat(substring($sp,1,@col - $col),substring($value,1,@length))" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="preceding-sibling::*"><xsl:text>&#10;</xsl:text></xsl:if>
        <xsl:value-of select="concat(substring($sp,1,@col),substring($value,1,@length))" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>