【发布时间】:2020-06-23 08:20:24
【问题描述】:
我有一个 C# 应用程序,它使用 OpenXML 从单词 (.docx) 文件中读取文本。
一般来说,有一组段落 (p),其中包含运行元素 (r)。 我可以使用
遍历 Run 节点foreach ( var run in para.Descendants<Run>() )
{
...
}
在一个特定的文档中有一个文本“START”,它分为三个部分,“ST”、“AR”和“T”。它们中的每一个都由一个 Run 节点定义,但在两种情况下,Run 节点包含在“smartTag”节点中。
<w:smartTag w:uri="urn:schemas-microsoft-com:office:smarttags" w:element="PersonName">
<w:r w:rsidRPr="00BF444F">
<w:rPr>
<w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
<w:b/>
<w:bCs/>
<w:sz w:val="40"/>
<w:szCs w:val="40"/>
</w:rPr>
<w:t>ST</w:t>
</w:r>
</w:smartTag>
<w:smartTag w:uri="urn:schemas-microsoft-com:office:smarttags" w:element="PersonName">
<w:r w:rsidRPr="00BF444F">
<w:rPr>
<w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
<w:b/>
<w:bCs/>
<w:sz w:val="40"/>
<w:szCs w:val="40"/>
</w:rPr>
<w:t>AR</w:t>
</w:r>
</w:smartTag>
<w:r w:rsidRPr="00BF444F">
<w:rPr>
<w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
<w:b/>
<w:bCs/>
<w:sz w:val="40"/>
<w:szCs w:val="40"/>
</w:rPr>
<w:t xml:space="preserve">T</w:t>
</w:r>
据我所知,OpenXML 不支持 smartTag 节点。结果,它只生成 OpenXmlUnknownElement 节点。
让这变得困难的是,它为 smartTag 的所有后代节点生成 OpenXmlUnknownElement 节点。这意味着我不能简单地获取第一个子节点并将其转换为 Run。
获取文本(通过 InnerText 属性)很容易,但我还需要获取格式信息。
有没有比较简单的方法来处理这个问题?
目前,我最好的想法是编写一个去除智能标签节点的预处理器。
编辑
跟进 Cindy Meister 的评论。
我使用的是 OpenXml 版本 2.7.2。正如 Cindy 所指出的,OpenXML 2.0 中有一个 SmartTagRun 类。我不知道那门课。
我在What's new in the Open XML SDK 2.5 for Office页面找到了以下信息
智能标签
由于 Office 2010 中已弃用智能标记,因此 Open XML SDK 2.5 不支持与智能标记相关的 Open XML 元素。 Open XML SDK 2.5 仍然可以将智能标记元素视为未知元素, 但是适用于 Office 的 Open XML SDK 2.5 Productivity Tool 验证 Office 文档文件中的那些元素(请参见以下列表)为 无效标签。
所以听起来可能的解决方案是使用 OpenXML 2.0。
【问题讨论】:
-
一些想法...我认为
para.Descendants<Run>也应该在smartTag中选择运行?您是说 SDK 区分嵌套在w:smartTag中的w:r? (我无法测试,因为 Word 不再支持创建 SmartTags - 有一个法庭案件裁定 MS 使用了另一家公司的专利技术,因此必须剥离该功能。) -
假设是 ^^ 那么是否可以检查 document.xml 中的这些元素(不使用 SDK)并在使用 SDK 之前将其删除?
-
para.Descendents<Run>不会获取 smartTag 中的 Runs。 smartTag 和所有后代节点都创建为 OpenXmlUnknownElement 节点。 -
去除smartTag 元素是个好主意,但我不完全确定如何去做。在使用 OpenXML 之前,我是否必须解压缩 docx 文件、编辑 document.xml 文件并重新打包,或者是否有一些支持 OpenXML 来预处理文件。
-
我已经有一段时间没有真正使用 SDK 进行编码了,这就是为什么我如此犹豫......在 VBA 中我知道我可以做到这一点;我认为应该可以使用 SDK,因为(我记得)可以获得零件或树的一部分的“纯”XML?操作它,然后再写回去?当然,.NET Framework Packaging 命名空间将允许直接访问 document.xml(这就是 SDK 在后台所做的事情)。可能值得提出一个新问题,专门关于阅读/编辑 Office ZIP 包的 XML(IOW 不强调 SmartTag 部分)。
标签: c# openxml openxml-sdk