首页 > 解决方案 > 飞碟无法识别 html 实体

问题描述

我正在尝试使用 html 文件作为 pdf 的模板,但 Flying Saucer 无法识别 HTML5 实体(&trade、  等)。如果我用它们的十六进制值替换它们,那么程序运行良好。

我的代码如下:

  public static InputStream create(String content) throws PDFUtilException {

try (ByteArrayOutputStream baos = new ByteArrayOutputStream();) {
  ITextRenderer iTextRenderer = new ITextRenderer();
  iTextRenderer.getSharedContext()
               .setReplacedElementFactory(new MediaReplacedElementFactory(iTextRenderer.getSharedContext()
                                                                                       .getReplacedElementFactory()));

  iTextRenderer.setDocumentFromString(closeOutTags(content), null);
  iTextRenderer.layout();
  iTextRenderer.createPDF(baos);
  return new ByteArrayInputStream(baos.toByteArray());
} catch (IOException | DocumentException e) {
  throw new PDFUtilException("Unable to create PDF", e);
}

}

谢谢,

奥利弗

标签: javahtmlxmlflying-saucer

解决方案


Michael 说 Flying Saucer 需要格式良好的 XML 是正确的,但如果您唯一的问题是预定义的 HTML 实体(它们不是 XML 的一部分),那么您可以在文档开头自己声明它们,如下所示:

<!DOCTYPE html [
  <!ENTITY % htmlentities SYSTEM "https://www.w3.org/2003/entities/2007/htmlmathml-f.ent">
  %htmlentities;
]>
<!-- your XHTML text following here -->

这会将实体声明从其官方 URL 拉入htmlentities参数实体,然后引用(例如“执行”)拉入的声明。如果您只需要tradeand nbsp,或者如果飞碟不允许您从网络访问 URL,您也可以手动声明它们:

<!DOCTYPE html [
  <!ENTITY trade "&#x02122;">
  <!ENTITY nbsp "&#x000A0;">
]>
<!-- your XHTML text following here -->

现在,如果您实际上有一个正确的 HTML(不是 XHTML)文件,那么您将无法直接使用 XML 处理器,因为 HTML 使用 XML 不支持的标记功能(例如,空元素,如img元素,省略的标签和属性缩写)。但是您可以使用 SGML 处理器首先将 HTML 转换为 XHTML (XML),然后对结果 XML 文件使用 Flying Saucer(SGML 是 HTML 和 XML 的超集,也是 HTML 和 XML 所基于的原始标记语言)。该过程涉及使用 HTML DTD 语法,例如原始的 W3C HTML4 DTD(从 1999 年开始)或我在 sgmljs.net上的 HTML5 DTD 以及 SGML 处理器。不过,在详细介绍之前,请先检查是否仅添加已描述的实体声明可以解决您的问题。


推荐阅读