dotnet OpenXML 元素 cNvPr NonVisual Drawing Properties 重复 id 标识处理
使用 OpenXML 的格式的 Office 文档的元素,使用 p:cNvPr Non-Visual Drawing Properties 的 Id 属性作为标识,在标准协议这个标识是唯一的,但实际很多文档都存在重复的标识。本文告诉大家在使用 Office 2016 版本测试重复 id 的行为
在 OpenXML 的元素的标识一个好的设计是使用 uint 作为标识符,这样做的兼容能力更强。因为可以做到在存在标识符不存在以及重复的时候,自动处理
在 OpenXML 里面的元素在 xml 文档的顺序和元素的序号顺序没有关系,有很多文档的 xml 里面存放的元素的 id 标识的大小和元素所在 xml 的顺序是不同的
在 Office 里,将会尝试给存在重复的标识的元素重新按照在 xml 的顺序给定一个序号作为元素标识
重复 id 标识的规则如下
元素重复选第一个
如有两个元素的标识都是相同的,同时在动画被使用,那么动画将会选择在 xml 第一个读到相同的 id 的元素
<p:cSld>
<p:spTree>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="3" name="林德熙的元素" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<!-- 忽略代码 -->
</p:sp>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="3" name="林德熙的元素" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<!-- 忽略代码 -->
</p:sp>
</p:spTree>
</p:cSld>
<p:timing>
<p:tnLst>
<p:par>
<!-- 忽略代码 -->
<p:tgtEl>
<p:spTgt spid="3" />
</p:tgtEl>
<!-- 忽略代码 -->
</p:par>
</p:tnLst>
</p:timing>
可以看到上面的元素有两个元素使用了 id="3"
同时动画也使用 spid="3"
的元素,在 PPT 选择在 xml 第一个读到的元素
测试课件请点击 元素重复选第一个.pptx 下载
元素不存在按序号
如果有动画等引用的元素的 id 是不存在的,但是在页面里面存在元素的 id 是重复的,如下面代码
<p:cSld>
<p:spTree>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="3" name="林德熙的元素" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<!-- 忽略代码 -->
</p:sp>
<p:sp>
<p:nvSpPr>
<p:cNvPr id="3" name="林德熙的元素" />
<p:cNvSpPr />
<p:nvPr />
</p:nvSpPr>
<!-- 忽略代码 -->
</p:sp>
</p:spTree>
</p:cSld>
<p:timing>
<p:tnLst>
<p:par>
<!-- 忽略代码 -->
<p:tgtEl>
<p:spTgt spid="2" />
</p:tgtEl>
<!-- 忽略代码 -->
</p:par>
</p:tnLst>
</p:timing>
元素 id 序号列表是 1 3 3 4 5 6 但没有动画引用的 spid="2"
的元素
因为元素 id 是 uint 的,可以按照 xml 的顺序,将重复的元素重新给序号作为标识。例如上面的序号里面,就存在两个元素都是重复的 3 作为标识。此时第二个使用 3 作为标识的元素将会被作为无标识元素,再根据按照顺序所缺少的标识重新设置。上面代码缺少了一个 2 的标识,因此就将第二个使用 3 作为标识的元素的标识修改为 2 作为标识
测试课件请点击 元素不存在按序号.pptx 下载
按照这个规则,如果元素的 id 序号列表是 1 3 3 3 5 6 而有两个动画分别应用 spid="2"
和 spid="4"
的元素,按照上面的规则,将按照序号重新给定重复的标识的元素新的值。将会给第二个使用 3 作为标识的元素的标识修改为 2 作为标识,给第三个使用 3 作为标识的元素的标识修改为 4 作为标识
更多请看 Office 使用 OpenXML SDK 解析文档博客目录
- Nodejs学习笔记(十四)— Mongoose介绍和入门
- 厚土Go学习笔记 | 13. 用循环和函数 实现Sqrt(x)
- 代码审计| 这是一款适合练手的漏洞
- 工具| NSE漏洞审计和渗透脚本的demo
- Windows Server 2008 R2 配置Exchange 2010邮件服务器并使用EWS发送邮件
- 厚土Go学习笔记 | 12. if 语句
- 厚土Go学习笔记 | 11. for循环 go语言只有for循环
- 从编译原理看一个解释器的实现
- 厚土Go学习笔记 | 10. 常量 与 数值常量
- Unity应用架构设计(7)——IoC工厂理念先行
- 厚土Go学习笔记 | 09. 类型转换 与 类型推导
- 厚积薄发,拥抱 .NET 2016
- 厚土Go学习笔记 | 08. 零值
- Unity应用架构设计(10)——绕不开的协程和多线程(Part 1)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 这 5 个 VSCode 扩展提高你的开发效率
- 猿实战18——商品发布之类目选择
- 树莓派基础实验1:双色LED灯实验
- 【机器学习基础】机器学习中类别变量的编码方法总结
- 树莓派基础实验2:RGB-LED实验
- 【Python基础】Python画王者荣耀英雄能力雷达图
- 树莓派基础实验4:继电器实验
- 树莓派基础实验5:激光传感器实验
- 树莓派基础实验6:轻触开关按键实验
- 从 lsof 开始,深入理解 Linux 虚拟文件系统!
- 原来 8 张图,就可以搞懂「零拷贝」了
- 构造函数没有返回值是怎么赋值的?
- 高频手撕算法合集来了!
- 面试官:兄弟,说说 ArrayList 和 LinkedList 有什么区别
- 开源中文关系抽取框架,来自浙大知识引擎实验室