XSL/FO:在“fo:block”上遇到无效属性:在将 html 转换为 PDF (xhmtml2fo) 时显示(没有可用的上下文信息)
Posted
技术标签:
【中文标题】XSL/FO:在“fo:block”上遇到无效属性:在将 html 转换为 PDF (xhmtml2fo) 时显示(没有可用的上下文信息)【英文标题】:XSL/FO: Invalid property encountered on "fo:block": display (No context info available) while converting html to PDF (xhmtml2fo) 【发布时间】:2020-01-13 03:56:06 【问题描述】:我正在使用将 html 转换为 PDF 的 XSL/FO 生成 PDF。
我正在使用 XSL/FO 样式表,它会生成一个 .fo 文件。 Apache FOP 从 .fo 文件生成一个 pdf。
在我的 html 文件中有很多包含“显示”内联 css 属性的标签,因为出现以下错误:
javax.xml.transform.TransformerException: org.xml.sax.SAXParseException; systemId:文件:/E:/Projects/PDF/xhtml2fo.xsl;行号:484;列号:44;在“fo:block”上遇到无效属性:显示(没有可用的上下文信息)
原因:org.apache.fop.fo.ValidationException:在“fo:block”上遇到无效属性:显示(没有可用的上下文信息) 在 org.apache.fop.events.ValidationExceptionFactory.createException(ValidationExceptionFactory.java:38) 在 org.apache.fop.events.EventExceptionManager.throwException(EventExceptionManager.java:58) 在 org.apache.fop.events.DefaultEventBroadcaster$1.invoke(DefaultEventBroadcaster.java:173) 在 com.sun.proxy.$Proxy65.invalidProperty(未知来源) 在 org.apache.fop.fo.PropertyList.handleInvalidProperty(PropertyList.java:557) 在 org.apache.fop.fo.PropertyList.convertAttributeToProperty(PropertyList.java:476) 在 org.apache.fop.fo.PropertyList.addAttributesToList(PropertyList.java:386) 在 org.apache.fop.fo.FObj.processNode(FObj.java:124) 在 org.apache.fop.fo.FOTreeBuilder$MainFOHandler.startElement(FOTreeBuilder.java:291) 在 org.apache.fop.fo.FOTreeBuilder.startElement(FOTreeBuilder.java:179) 在 org.apache.xalan.transformer.ResultTreeHandler.flushElem(ResultTreeHandler.java:860) ... 72 更多
带有显示属性的html代码:
<div id="something" style="display:block;">Some value</div>
我们如何在 xsl 中包含“显示”样式的部分处理:
<xsl:template name="process-style">
【问题讨论】:
为了让任何人帮助您,您需要包含用于生成 xsl-fo 的 xslt。我假设(基于阅读你的问题)你正在做一些事情,比如将每个 div 变成一个 fo 块,并复制属性,不幸的是,在 fo 块上不允许使用 style 属性,因此你不能这样做。相反,您必须以不同的方式设置所有 fo 元素的样式。 感谢您的回复。我可以包含 xsl 但不能包含 xslt。与从 HTML 转换 PDF 的过程一样,xslt 是在过程中间生成的(并且不能存储)。您能否详细说明“以不同方式设置所有 fo 元素的样式”,这确实会有所帮助。 好的,那么我认为您不在正确的组中。无论您使用什么工具从结构中生成 xslt,您都应该将您的问题标记为关于并询问与该工具相关的问题。我将把这个问题标记为当前形式不可挽救。尝试再次询问您生成 xslt 然后生成 xsl-fo 的工具。 也许您使用的 XSL 会分开并按原样使用属性。属性“display”不是有效的 XSL FO。不超过“-moz-border-radius”是有效的。您需要找到将 CSS 样式转换为“有效”XSL FO 的 XSL。 【参考方案1】:也许这可以帮助您整理出适合您的软件包。网上有一个应用程序http://www.cloudformatter.com/CSS2Pdf。
此应用程序可在现有浏览器中提取 <div>
或 <div>
,并从所有来源解析所有 CSS,将其构建为 XML 并发送到格式。作为该格式的一部分,是一个将内容转换为 XSL FO 的 XSL。 XSL 就在这里。
http://xep.cloudformatter.com/doc/XSL/xeponline-fo-translate-2.xsl
如果您查看此 XSL(是的,它是 1.0,并且在 2.0 中可能更有效),您会发现所有 style
属性被递归解析以分解然后创建 XSL FO 属性的部分来自他们。
从第 1593 行开始:
<xsl:template name="processCSSStyle">
<xsl:param name="cssString"/>
<xsl:param name="type"/>
<xsl:param name="float"/>
<xsl:param name="ignoreHeight"/>
<xsl:call-template name="processCSSEntry">
<xsl:with-param name="attr" select="normalize-space(substring-before($cssString, ': '))"/>
<xsl:with-param name="value"
select="normalize-space(substring-after(substring-before($cssString, '; '), ': '))"/>
<xsl:with-param name="cssRemaining" select="substring-after($cssString, '; ')"/>
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="float" select="$float"/>
<xsl:with-param name="ignoreHeight" select="$ignoreHeight"/>
</xsl:call-template>
</xsl:template>
查看style
中的 CSS 样式列表。
<xsl:template name="processCSSEntry">
<xsl:param name="attr"/>
<xsl:param name="value"/>
<xsl:param name="cssRemaining"/>
<xsl:param name="type"/>
<xsl:param name="float"/>
<xsl:param name="ignoreHeight"/>
<xsl:if test="$attr">
<xsl:call-template name="handleAttr">
<xsl:with-param name="attr" select="$attr"/>
<xsl:with-param name="value" select="$value"/>
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="float" select="$float"/>
<xsl:with-param name="ignoreHeight" select="$ignoreHeight"/>
</xsl:call-template>
<xsl:call-template name="processCSSEntry">
<xsl:with-param name="attr" select="normalize-space(substring-before($cssRemaining, ': '))"/>
<xsl:with-param name="value"
select="normalize-space(substring-after(substring-before($cssRemaining, '; '), ': '))"/>
<xsl:with-param name="cssRemaining" select="substring-after($cssRemaining, '; ')"/>
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="float" select="$float"/>
<xsl:with-param name="ignoreHeight" select="$ignoreHeight"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
最终,这些单独的事情在选择/何时结构中进行处理,如下所示:
<xsl:when test="$attr = 'margin-left'">
<xsl:attribute name="margin-left">
<xsl:value-of select="$value"/>
</xsl:attribute>
</xsl:when>
因此,它将style
属性分解为它的组件并制作XSL FO 属性。
我不会发布更多内容,因为您可以下载并检查 XSL。因为它来自浏览器内容,所以这里应用了许多规则,这些规则可能与去除 XSL FO 中没有意义的属性以及对 XSL FO 和 HTML 不同区域的非常具体的处理无关。
【讨论】:
以上是关于XSL/FO:在“fo:block”上遇到无效属性:在将 html 转换为 PDF (xhmtml2fo) 时显示(没有可用的上下文信息)的主要内容,如果未能解决你的问题,请参考以下文章
XSL FO 在具体注释之后读取第一个 fo:table 节点