Xml 使用FOP修复PDF中一行中单词的位置
我正在尝试实现FOP,以便使用XML和XSLT文件输出PDF 我的问题是,我需要确定单词在一行中的位置(但不是通过使用表格),例如: 我有以下xml: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
<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> </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> </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>