如何使用Itext 7-dotnet实现类似Acrobat标记PDF背景元素的功能
解决方案
你之前的写法只是将结构标签的角色设为Artifact,相当于在标签树里保留了一个无意义的Artifact节点,本质上没有给内容本身打标记,所以直接删除节点就会触发PAC3的未标记内容报错。Adobe Acrobat的处理逻辑是先给内容本身打Artifact标记,再移除对应标签树节点,所以不会触发校验问题。
正确的操作步骤和修正代码如下:
tagTreePointer.MoveToKid(0); for (int kidIndex = tagTreePointer.GetKidsRoles().Count - 1; kidIndex >= 0; kidIndex--) { var kidsRole = tagTreePointer.GetStandardRoleOfKid(kidIndex); if (!kidsRole.Equals(PdfName.Span.GetValue(), StringComparison.Ordinal)) continue; tagTreePointer.MoveToKid(kidIndex); if (tagTreePointer.GetKidsRoles() is IList<string> kidsRoles && kidsRoles.Count == 1 && kidsRoles.FirstOrDefault() is string kidKidRole && kidKidRole.Equals(PdfName.MCR.GetValue(), StringComparison.OrdinalIgnoreCase)) { if (tagTreePointer.GetContext().GetPointerStructElem(tagTreePointer) is PdfStructElem pdfStructElement) { if (pdfStructElement.GetKids().FirstOrDefault() is PdfMcrNumber pdfMcrNumber) { // 第一步:获取MCR关联的页面对象,将对应MCID的内容标记为Artifact var page = pdfMcrNumber.GetPageObject(); int mcrId = pdfMcrNumber.GetMcid(); page.GetMcidProperties(mcrId).SetArtifact(new PdfArtifact()); // 第二步:移除当前Span标签节点,不需要保留在标签树中 tagTreePointer.Remove(); } } } // 指针回退到父节点,继续遍历下一个子节点 tagTreePointer.MoveToParent(); }
这种处理方式和Acrobat的逻辑完全对齐:内容本身被标记为Artifact后,就不需要再出现在标签树中,PAC3扫描时会识别该内容为背景元素,不会触发未标记内容的报错。如果需要区分Artifact类型(如页眉、页脚、背景图),可以给PdfArtifact设置对应的类型属性,适配更精细的可访问性校验规则。
内容的提问来源于stack exchange,提问作者Lutze
相关产品推荐
相关产品推荐

