首页 > 解决方案 > “从选择中查找标签”在标记的 pdf 中不起作用?

问题描述

我已经使用 pdfbox 标记了一个 pdf。

我是如何被标记的:我没有提取文本和标记,而是将 mcid 添加到现有内容流(打开和关闭 ex:/p<< MCID 0 >> BDC .. .. .. EMC),然后我添加了标记内容以记录根目录结构。

什么工作:几乎所有东西都像完全标记的pdf一样工作正常。它也通过了 PAC3 可访问性检查器。

//Adding tags
tokens.add(++ind, type_check(t_ype, page));
currentMarkedContentDictionary = new COSDictionary();
currentMarkedContentDictionary.setInt(COSName.MCID, mcid);
if (altText != null && !altText.isEmpty()) {
    currentMarkedContentDictionary.setString(COSName.ALT, altText);
}
mcid++;
tokens.add(++ind, currentMarkedContentDictionary);
tokens.add(++ind, Operator.getOperator("BDC"));

// Adding marked content to root structure
structureElement.appendKid(markedContent);

currentSection.appendKid(structureElement);             

什么不起作用:标记一个未来后标记结构中缺少。有一个名为“从选择中查找标签”的选项。不管用。当我选择一些测试并在根结构中按“从选择中查找标签”时,它将是最后一个标签。请在下面的链接中找到 pdf。

https://drive.google.com/file/d/11Lhuj50Bb9kChvD0kL_GOHQn4RNKZ0hR/view?usp=sharing

父树:

https://drive.google.com/file/d/109xhUpqsQSFLPJB2nhXoU9ssMKnyht3G/view?usp=sharing

带有标记和父树的额外文档: https ://drive.google.com/file/d/1yzZSsjkb5_dGfq1Wu3VxsH73vr3alRmC/view?usp=sharing

请帮我解决这个问题。

新问题: 我观察到

在 Jaws 阅读我标记的文档时,我正在按下 windows machine 中的 ctl+shift+5 之类的控件。它将显示下拉>“基于标记结构读取”或>“从左上到右下”和两个单选按钮下方的选项

阅读当前页面 阅读您可以看到的所有页面图像。adobe dc 中的 Shift+CTL+5 您可以在此处查看图像

我选择了“基于标记结构阅读并阅读当前页面”现在下巴不阅读标记结构。但是,如果我对“阅读整个文档”使用相同的文档,它是否阅读完美?

链接到文档:

https://drive.google.com/file/d/1CguMHa4DikFMP15VGERnPNWRq5vO3u6I/view?usp=sharing

有什么帮助吗?

标签: javapdfitextpdfbox

解决方案


嵌套问题

我是如何被标记的:我不是提取文本和标记,而是将 mcid 添加到现有的内容流中(打开和关闭 ex: /p<< MCID 0 >> BDC .. .. .. EMC

你这样做不正确。例如,请参阅文档中页面内容流的开头:

BT
0 i
/C0_0 18 Tf
41.91 740.175 Td
/H2 <</MCID  0  >> BDC
( \) F M M P  8 P S M E) Tj
ET
/TouchUp_TextEdit MP
BT
/C0_1 14 Tf
EMC 

关注文本对象和标记内容的开头和结尾,我们看到您有BT ... BDC ... ET ... BT ... EMC

但是,根据规范:

当标记内容运算符BMCBDCEMC与文本对象运算符BTET组合时(参见 9.4,“文本对象”),每对匹配的运算符(BMC ...<strong>EMC, BDC ...<strong> EMC 或BT …<strong>ET) 应正确(单独)嵌套。因此,序列

BMC             BT
  BT              BMC
    …    and         …
  ET              EMC
EMC             ET

是有效的,但是

BMC             BT
  BT              BMC
    …    and         …
  EMC             ET
BT              EMC

无效。

(ISO 32000-1 第 14.6 节“标记内容”)

此问题已在第二个共享 PDF 中修复,res1.pdf.

缺少 ParentTree 和 StructParents

你的问题关注的问题是

有一个名为“从选择中查找标签”的选项。不管用。

从选择中查找标签本质上意味着您具有某些内容流指令的MCID,并且您在结构树中搜索引用该标记内容 ID 的结构元素。

PDF 处理器应如何执行此操作,在 PDF 规范 ISO 32000-1 的第 14.7.4.4 节“从内容项中查找结构元素”(或 ISO 32000-2 中的第 14.7.5.4 节)中进行了描述:

因为流不能包含对象引用,所以标记为内容序列的内容项无法直接引用回其父结构元素(它们作为内容项所属的结构元素)。相反,应为此目的提供不同的机制,即结构父树。为保持一致性,作为整个 PDF 对象(例如 XObject)的内容项也应使用父树来引用其父结构元素。

父树是一个数字树,从文档结构树根中的ParentTree条目访问。对于作为至少一个结构元素的内容项的每个对象和每个包含至少一个作为内容项的标记内容序列的内容流,该树都应包含一个条目。

您的 PDF 根本没有该ParentTree,并且您的页面不包含要在父树中查找的StructParents条目。因此,从标记内容结构树的规定方式是不可能的。

在第三个共享 PDF 中添加了ParentTreenew.pdf,.

不正确的父树条目

new.pdf你有一个ParentTree时,它​​的内容显然是不正确的:

屏幕截图父树

ParentTree是一个数字树,即整数被映射到这里的某个东西,因此显然不能有多个条目用于同一个整数键。

此外,查看其中一个值:

屏幕截图 ParentTree,第一个条目打开

可以看到您声称以下StructElem是所有标记的内容 ID 的值:

所有内容 ID 的共同值

进一步检查这个StructElem,可以看到它代表最后一页上的最后一段。

因此,您的观察

现在不是“未找到选择”,而是突出显示父树中的最后一个 <P> 标记。不管我们选择了什么。

是可以期待的。如果有人期望任何合理的行为,那就是ParentTree结构被严重破坏。

实际上不仅有这个new.pdf,还有res.pdftagged without altext.pdfParentTree ,但是所有这些ParentTree都像树一样被破坏new.pdf

在分析不需要的行为时,您可能希望开始检查您创建的结构。

父树条目的另一个问题

同时,父树中先前描述的问题已得到解决,不同的页面现在具有不同的结构父级,并且父树数组现在引用不同 MCID 的结构元素。

但是,对于某些文档,现在会出现不同的错误,例如“res29_08_19.pdf”。这里的父树是这样开始的:

屏幕截图父树

特别是数组中的第一个条目用于 MCID 3,第二个用于 MCID 4,...

这是无效的,根据规范

应使用序列的标记内容标识符作为数组中从零开始的索引来找到每个序列对应的数组元素。

(ISO 32000-1 第 14.7.4.4 节“从内容项中查找结构元素”)

因此,第一个条目必须用于 MCID 0,第二个条目必须用于 MCID 1,...

你在评论中反对

不,我将 0 和 1 Mcid 用于 Artifacts。

但作为上述推论:不要将 MCID 分配给没有结构元素的标记内容序列!MCID 用于在结构层次结构和内容流之间来回切换。如果您在没有结构元素的情况下标记一段内容,请不要给它一个 MCID。

父树条目的另一个问题

您再次报告最新文件mathpdf.pdf的问题。确实存在问题;Adobe Acrobat Preflight 报告了一个 5 页的不一致父树映射列表,如下所示:

飞行前报告摘录

与之前的问题相比,仅看父树并不能清楚原因,还必须查看结构层次结构。

但是,这样做会立即引起注意:在您的父树中,您没有引用 MCID 的实际父结构元素,而是引用了一个新的结构树节点,该节点声称将结构层次结构中的实际父节点作为其自己的父母(实际上不是它的孩子之一),并且还声称有问题的 MCID 作为孩子。

例如,让我们看看第一页上的 MCID 0。在结构层次结构中,您有:

结构层次截图

在父树中,您有:

父树截图

您应该直接从第一页的父树数组引用对象 238(MCID 0 的结构层次结构父级),而不是声称将对象 238 作为父级和 MCID 0 作为子级的中间对象 62。

报告的不一致可能是由于从父树(在对象 62 中)引用的节点声称是P段落,而父节点(在对象 238 中)是Span。这是不允许的,一个段落可能包含一个跨度,但它不能包含在一个中。


推荐阅读