如何在ANSI C中提取AF条目无效的PDF测试文档(Testdoc)的附件?
如何在ANSI C中提取AF条目无效的PDF测试文档(Testdoc)的附件?
看起来你踩了PDF附件提取的常见坑——只依赖ZUGFeRD规范里的AF数组,遇到不合规或者结构特殊的文档就卡壳了。别担心,纯ANSI C完全能搞定这个问题,我们得把搜索范围扩大,覆盖PDF里存储附件的所有标准位置,一步一步来:
第一步:先查PDF的标准嵌入式文件入口
PDF规范里,嵌入式文件的标准存储位置是文档目录(Catalog)的/EmbeddedFiles条目,这个和ZUGFeRD的AF数组是独立的,很多不合规的文档会忽略AF,但不会漏掉这个标准位置。
用纯C处理的话,你可以这么做:
- 先解析PDF的Catalog字典(通常在交叉引用表的根对象,比如
1 0 R这类,具体看交叉引用表的根条目) - 在Catalog里查找
/EmbeddedFiles键,它的值要么是一个/Names字典,要么是一个名称树(/Tree字典) - 如果是
/Names字典,直接取/Names数组,每两个元素一组(第一个是文件名,第二个是文件规范字典) - 如果是名称树,要递归遍历:名称树的节点分叶子节点(
/Kids为空,/Names数组存条目)和分支节点(/Kids是子节点数组,递归处理每个子节点) - 拿到文件规范字典后,就用你之前的逻辑:取
/EF字典,然后读取对应的流内容就行
第二步:扫描页面上的文件附件注释
有些附件是直接“钉”在页面上的注释里,这种情况AF数组和顶层/EmbeddedFiles都可能没记录,得单独查页面注释:
- 遍历PDF的每个页面对象(从Catalog的
/Pages字典开始,递归遍历所有子页面) - 每个页面的
/Annots数组里,找/Subtype为/FileAttachment的注释 - 这类注释里的
/F键就对应文件规范字典,同样提取/EF的流内容
第三步:检查ZUGFeRD的 fallback 结构
虽然Testdoc的AF无效,但它毕竟是ZUGFeRD相关文档,还可以补查这几个点:
- 检查Catalog的
/MetaData里的XML元数据,看是否有指向附件的引用(不过这个概率低,更多是元数据本身) - 查看是否有
/Package字典,有些ZUGFeRD文档会把核心附件放在这里,里面的/Files数组就是文件规范的集合
纯C实现的关键注意点
要让这些逻辑在纯C里跑通,你得确保你的PDF解析代码能处理这些细节:
- 正确解析间接对象:PDF里很多字典/数组元素是类似
15 0 R的间接引用,不能直接当成字典解析,得去交叉引用表找到对应对象的偏移量,再读取实际内容 - 处理流的解密:如果Testdoc有加密,你得先根据文档的加密字典(Catalog的
/Encrypt)解密流内容,才能拿到真实的附件数据 - 递归遍历复杂结构:名称树、页面树都是分层的,得用递归或者循环来遍历所有节点,不能只处理第一层
总之,别再死磕AF数组了,先从标准的嵌入式文件入口查起,再覆盖页面注释和ZUGFeRD的其他可能位置,纯C完全能实现这些逻辑——本质就是把PDF的基础对象解析逻辑补全,覆盖所有附件存储的场景。
内容来源于stack exchange
相关产品推荐
相关产品推荐

