dotnet OpenXML 解析 WPS 不规范的 PPT 文件的 cNvPr 重复 id 问题

2023-10-17 15:59

本文主要是介绍dotnet OpenXML 解析 WPS 不规范的 PPT 文件的 cNvPr 重复 id 问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在收到了反馈说有一份课件,打开解析就发现替换的元素不对,原因是这个课件里面的 Slide Master 里面存在一个元素的 id 和某个页面的元素 id 是相同的,这不符合 ECMA 376 的规范。通过读取文档的内容,发现这是 WPS 制作出来的 PPT 文件。本文做一个存档,用来告诉大家有这个坑

在 Office 2016 和 Office 2019 的行为判断请看以下两篇博客

dotnet OpenXML 元素 cNvPr NonVisual Drawing Properties 的属性作用

dotnet OpenXML 元素 cNvPr NonVisual Drawing Properties 重复 id 标识处理

上面博客对于相同页面里面存在重复的 id 处理比较简单,但是对于在 Slide Master 里面存在一个元素的 id 和某个页面的元素 id 是相同的比较坑,但是做法就是将 Slide Master 里面存在相同 id 元素当成比较先发现的元素

下面咱来看看这份有趣的课件,测试课件请点击 解析 WPS 不规范的 PPT 文件的 cNvPr 重复 id 问题.pptx 下载

在这份课件的 SlideMaster1.xml 文件里面,可以看到有如下定义

      <p:sp><p:nvSpPr><p:cNvPr id="7" name="KSO_TEMPLATE" hidden="1" /><p:cNvSpPr /><p:nvPr userDrawn="1"><p:custDataLst><p:tags r:id="rId8" /></p:custDataLst></p:nvPr></p:nvSpPr><p:spPr><a:xfrm><a:off x="0" y="0" /><a:ext cx="0" cy="0" /></a:xfrm><a:prstGeom prst="rect"><a:avLst /></a:prstGeom></p:spPr><!-- 忽略代码 --></p:sp>

根据 dotnet OpenXML 元素 cNvPr NonVisual Drawing Properties 的属性作用 可以了解到 p:cNvPr 的 id 就是元素的 id 属性

这个元素的属性是 7 同时有趣的是 name="KSO_TEMPLATE" 表示了这是 KSO 金山的 Template 模版

这个元素的 X 和 Y 和 宽度高度根据 a:xfrm 可以看到都是 0 没有宽度和高度,特别诡异

在页面 Slide1.xml 文件里面,可以看到里面有一个元素,这个元素的 p:cNvPr 也是 7 如下面代码

      <p:sp><p:nvSpPr><p:cNvPr id="7" name="标题 6" /><p:cNvSpPr txBox="1" /><p:nvPr><p:custDataLst><p:tags r:id="rId2" /></p:custDataLst></p:nvPr></p:nvSpPr><!-- 忽略代码 --></p:sp>

这个元素有一个有趣的属性,那就是 p:custDataLst 的值,这里面包含了 WPS 无文档的内容,可以看到 p:tags 通过 r:id 属性指向 rId2 的资源。在 Slide1.xml.rels 文件里面,可以看到下面代码

<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/tags" Target="../tags/tag12.xml"/>

也就是说加载了 tag12.xml 文件的内容,这个文件内容如下

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<p:tagLst xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"><p:tag name="KSO_WM_UNIT_HIGHLIGHT" val="0" /><p:tag name="KSO_WM_UNIT_COMPATIBLE" val="1" /><p:tag name="KSO_WM_UNIT_DIAGRAM_ISNUMVISUAL" val="0" /><p:tag name="KSO_WM_UNIT_DIAGRAM_ISREFERUNIT" val="0" /><p:tag name="KSO_WM_UNIT_LAYERLEVEL" val="1" /><p:tag name="KSO_WM_TAG_VERSION" val="1.0" /><p:tag name="KSO_WM_BEAUTIFY_FLAG" val="#wm#" /><p:tag name="KSO_WM_UNIT_ISCONTENTSTITLE" val="0" /><p:tag name="KSO_WM_UNIT_PRESET_TEXT" val="PART 01" /><p:tag name="KSO_WM_UNIT_NOCLEAR" val="0" /><p:tag name="KSO_WM_UNIT_VALUE" val="5" /><p:tag name="KSO_WM_UNIT_TYPE" val="e" /><p:tag name="KSO_WM_UNIT_INDEX" val="1" /><p:tag name="KSO_WM_TEMPLATE_CATEGORY" val="custom" /><p:tag name="KSO_WM_TEMPLATE_INDEX" val="20204217" /><p:tag name="KSO_WM_UNIT_ID" val="custom20204217_7*e*1" />
</p:tagLst>

可以看到这些都是 WPS 自己定义的内容,这样的课件在 Office 打开还是可以认的,只是还原效果没有在 WPS 上好。而在我自己的软件上,就凉凉了

这份课件可以通过 docProps\custom.xml 文件找到 WPS 应用的版本

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><property fmtid="{D5CDD505-2E9C-101B-9397-08002B2CF9AE}" pid="2" name="KSOProductBuildVer"><vt:lpwstr>2052-11.1.0.9198</vt:lpwstr></property>
</Properties>

这里的 KSOProductBuildVer 就是表示构建这份文档的 WPS 应用版本,而 2052-11.1.0.9198 是版本号

本文的属性是依靠 dotnet OpenXML 解压缩文档为文件夹工具 工具协助测试的,这个工具是开源免费的工具,欢迎小伙伴使用

更多请看 Office 使用 OpenXML SDK 解析文档博客目录

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

如有不方便在博客评论的问题,可以加我 QQ 2844808902 交流

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

这篇关于dotnet OpenXML 解析 WPS 不规范的 PPT 文件的 cNvPr 重复 id 问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/226454

相关文章

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言