如何将带有嵌入图像的 XHTML+CSS 转换为 XSL-FO?

Posted

技术标签:

【中文标题】如何将带有嵌入图像的 XHTML+CSS 转换为 XSL-FO?【英文标题】:How to transform XHTML+CSS with embedded images to XSL-FO? 【发布时间】:2021-06-28 14:42:48 【问题描述】:

我正在尝试将一个简单的 html 页面转换为 XSL-FO,以输入 Apache FOP 以进行 PDF 渲染。 步骤是:HTML+CSS -> XHTML -> XSL-FO -> PDF。

我已使用 java 库 CSSToXSLFO 将 XHTML 转换为 XSL-FO。这可行,但它无法处理嵌入的图像。

有什么工具可以改造

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>hello</title>
  </head>
  <body>
    <h1 style="color: green">Hello world!</h1>
    <img src="data:image/png;base64,iVBORw...=" />
  </body>
</html>

进入

    <fo:flow flow-name="xsl-region-body">
      <fo:block>
        <fo:block color="green">Hello world!</fo:block>
        <fo:external-graphic src="url(data:image/png;base64,iVBORw...=)" content- content- scaling="uniform"/>
      </fo:block>
    </fo:flow>

?

【问题讨论】:

您声明它尚无法处理 base64 编码图像,并且存在示例cloudformatter.com/CSS2Pdf.Demos.Images,因此我们需要更多信息。也许你的图片太大了? 【参考方案1】:

如果 FOP 处理器支持 fo:external-graphic 中的数据 URI,您当然可以使用 XSLT 将 XHTML 转换为 XSL-FO,例如

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    xpath-default-namespace="http://www.w3.org/1999/xhtml"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
        <fo:layout-master-set>
            <fo:simple-page-master master-name="sample">
                <fo:region-body/>
            </fo:simple-page-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="sample">
            <xsl:apply-templates select="html/body"/>
        </fo:page-sequence>
    </fo:root>
  </xsl:template>
  
  <xsl:template match="body">
      <fo:flow flow-name="xsl-region-body">
          <fo:block>
              <xsl:apply-templates/>
          </fo:block>
      </fo:flow>
  </xsl:template>
  
  <xsl:template match="h1">
      <fo:block>
          <xsl:apply-templates/>
      </fo:block>
  </xsl:template>
  
  <xsl:template match="img">
      <fo:external-graphic src="@src" content- content- scaling="uniform"/>    
  </xsl:template>
  
</xsl:stylesheet>

这是处理 h1img 元素的最小示例,我没有尝试将任何 HTML CSS style 属性拼写到 XSL-FO 表示属性转换,但您当然可以使用例如&lt;xsl:apply-templates select="@*, node()"/&gt; 而不是 &lt;xsl:apply-templates/&gt; 然后添加模板进行转换,例如style="color: green"color="green"。由于 CSS 有自己的非 XML 语法,显然为任意样式属性编写完整的解析器是一项超出 *** 答案范围的艰巨任务。

我也不太确定 XSL-FO 中允许的 src 属性语法,FOP 似乎理解直接 src="@src" 就好了,但是当然,要创建您在问题中指出的格式,您也可以使用src="url(@src)"

【讨论】:

以上是关于如何将带有嵌入图像的 XHTML+CSS 转换为 XSL-FO?的主要内容,如果未能解决你的问题,请参考以下文章

如何将html模板(带图像)转换为pdf?

CSS:如何将彩色图像转换为灰色或黑白图像[重复]

如何从 CSS 中引用嵌入的图像?

使用PHP将带有样式(css)的html转换为pdf

如何将外部 OCR 嵌入现有 PDF?

如何将带有 SVG 的 div#WareHouse 转换为图像