从字处理文档中移除隐藏文本

本主题演示如何使用 Open XML SDK for Office 中的类以编程方式删除字处理文档中的隐藏文本。


WordProcessingML 文档的结构

文档的基本文档结构WordProcessingML由 和 body 元素组成document,后跟一个或多个块级元素(例如 p表示段落)。 段落包含一个或多个 r 元素。 r代表 run,它是具有一组通用属性(如格式设置)的文本区域。 运行包含一个或多个 t 元素。 元素 t 包含文本范围。 下面的代码示例演示 WordprocessingML 包含文本“示例文本”的文档的标记。

    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
      <w:body>
        <w:p>
          <w:r>
            <w:t>Example text.</w:t>
          </w:r>
        </w:p>
      </w:body>
    </w:document>

使用 Open XML SDK,可以使用与元素对应的 WordprocessingML 强类型类创建文档结构和内容。 可以在 命名空间中找到 这些类。 下表列出了对应于 、、bodyrpt 元素的类的document类名。

WordprocessingML 元素 Open XML SDK 类 说明
<document/> Document 主文档部件的根元素。
<body/> Body 块级结构(如段落、表格、批注和 ISO/IEC 29500 规范中指定的其他项)的容器。
<p/> Paragraph 段落。
<r/> Run 一段连续文本。
<t/> Text 文本范围。

有关 WordprocessingML 文档的各个部分和元素的整体结构的详细信息,请参阅 WordprocessingML 文档的结构


Vanish 元素的结构

元素vanish在隐藏Word文件中的文本方面起着重要作用。 格式 Hidden 设置属性是一个切换属性,这意味着在样式定义中使用它和将其用作直接格式之间,其行为不同。 在用作样式定义的一部分时,设置此属性可切换其当前状态。 将其设置为 false (或等效) 会导致保持当前设置不变。 但是,当用作直接格式时,将其设置为 truefalse 设置生成的属性的绝对状态。

ISO/IEC 29500 规范中的以下信息介绍了 元素vanish

vanish(隐藏文本)

此元素指定在文档中显示时是否隐藏此连续文本的内容。 [备注:该设置应影响文本的正常显示,但应用程序可以使用设置来强制显示隐藏文本。 备注结束]

此格式属性为切换属性 (§17.7.3)。

如果不存在此元素,则默认值为保留样式 层次结构中上一级别应用的格式。 如果从未在样式层次结构中应用此元素,则此文本在文档中显示时不应隐藏。

[示例:考虑对连续文本内容打开隐藏文本属性的一段连续文本。 此约束使用以下 WordprocessingML 指定:

    <w:rPr>
      <w:vanish />
    </w:rPr>

此段连续文本声明,为此段连续文本的内容设置 vanish 属性,所以在显示文档内容时,将隐藏此段连续文本的内容。 示例结束]

© ISO/IEC 29500:2016

以下 XML 架构片段定义此元素的内容。

    <complexType name="CT_OnOff">
       <attribute name="val" type="ST_OnOff"/>
    </complexType>

val上述代码中的 属性是可以打开或关闭的二进制值。 如果给定的值 on1true 属性处于打开的状态。 如果给定的值 off0false 属性处于关闭状态。

代码的工作方式

方法 WDDeleteHiddenText 适用于指定的文档,并删除隐藏的所有 run 元素并删除额外的 vanish 元素。 代码首先使用 Open 方法打开文档,并指示应打开文档以 (最终 true 参数) 进行读/写访问。 给定打开的文档,代码使用 MainDocumentPart 属性导航到main文档,并将引用存储在变量中。

using (WordprocessingDocument doc = WordprocessingDocument.Open(docName, true))
{

获取消失元素的列表

代码首先检查 doc.MainDocumentPartdoc.MainDocumentPart.Document.Body 是否不为 null,并在缺少异常时引发异常。 然后使用 向其Descendants()传递 Vanish 类型来获取元素的 VanishIEnumerable并将其强制转换为列表。

if (doc.MainDocumentPart is null || doc.MainDocumentPart.Document.Body is null)
{
    throw new ArgumentNullException("MainDocumentPart and/or Body is null.");
}

// Get a list of all the Vanish elements
List<Vanish> vanishes = doc.MainDocumentPart.Document.Body.Descendants<Vanish>().ToList();

删除包含隐藏文本和额外消失元素的运行

若要删除隐藏的文本,我们接下来循环访问 List 元素的 Vanish 。 元素Vanish是 的子元素RunProperties,但RunProperties可以是 或 xref:DocumentFormat.OpenXml.Wordprocessing.ParagraphProperties> 的Run子元素,因此我们获取每个Vanish元素的父级和祖父级,检查其类型。 然后,如果祖父级是 , Run 则删除该运行,如果不是,则从父元素中删除 Vanish 子元素。

// Loop over the list of Vanish elements
foreach (Vanish vanish in vanishes)
{
    var parent = vanish?.Parent;
    var grandparent = parent?.Parent;

    // If the grandparent is a Run remove it
    if (grandparent is Run)
    {
        grandparent.Remove();
    }
    // If it's not a run remove the Vanish
    else if (parent is not null)
    {
        parent.RemoveAllChildren<Vanish>();
    }
}

示例代码

注意

此示例假定打开的文件包含一些隐藏文本。 为了隐藏一部分文件文字,请选择该文字,然后单击 Ctrl+D 显示"字体"对话框。 选择"隐藏"框并单击"确定"。

以下是使用 C# 和 Visual Basic 编写的完整示例代码。

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.Linq;


static void WDDeleteHiddenText(string docName)
{
    // Given a document name, delete all the hidden text.

    using (WordprocessingDocument doc = WordprocessingDocument.Open(docName, true))
    {

        if (doc.MainDocumentPart is null || doc.MainDocumentPart.Document.Body is null)
        {
            throw new ArgumentNullException("MainDocumentPart and/or Body is null.");
        }

        // Get a list of all the Vanish elements
        List<Vanish> vanishes = doc.MainDocumentPart.Document.Body.Descendants<Vanish>().ToList();

        // Loop over the list of Vanish elements
        foreach (Vanish vanish in vanishes)
        {
            var parent = vanish?.Parent;
            var grandparent = parent?.Parent;

            // If the grandparent is a Run remove it
            if (grandparent is Run)
            {
                grandparent.Remove();
            }
            // If it's not a run remove the Vanish
            else if (parent is not null)
            {
                parent.RemoveAllChildren<Vanish>();
            }
        }
    }
}

另请参阅