java - 飞碟无法识别 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);
}
}
谢谢,
奥利弗
解决方案
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
参数实体,然后引用(例如“执行”)拉入的声明。如果您只需要trade
and nbsp
,或者如果飞碟不允许您从网络访问 URL,您也可以手动声明它们:
<!DOCTYPE html [
<!ENTITY trade "™">
<!ENTITY nbsp " ">
]>
<!-- 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 处理器。不过,在详细介绍之前,请先检查是否仅添加已描述的实体声明可以解决您的问题。
推荐阅读
- android - Moshi 无法解析可为空的
- php - 合并PHP数组添加键
- mysql - 使用某些条件从sql中的多个表中检索数据
- reactjs - 运行构建时的空白页
- flutter - 我有一个颤振功能,可以使用 Firestore 数据库中的文本向 GoogleMaps 添加标记
- jquery - 单击后禁用laravel中的链接按钮
- c# - 在 .Net 中解压 Comp-3 时遇到问题。Comp-3 值中除符号字符外还有字母字符
- c - 如何在 C 中获取 Linux 的发行版
- java - Apache Flink 不返回空闲分区的数据
- syntax-highlighting - 如何在 Progress 11.6 AppBuilder 的部分编辑器和过程编辑器中获得语法高亮