Share via


Eliminar texto oculto de un documento de procesamiento de texto

En este tema se muestra cómo usar las clases del SDK de Open XML para Office para quitar mediante programación texto oculto de un documento de procesamiento de texto.


Obtención de un objeto WordprocessingDocument

Para abrir un documento existente, debe crear una instancia de la clase WordprocessingDocument como se muestra en la siguiente instrucción using. En la misma instrucción, se abre el archivo de procesamiento de texto con el fileName especificado mediante el método Open , con el parámetro booleano establecido en true para habilitar la edición del documento.

    using (WordprocessingDocument doc = 
        WordprocessingDocument.Open(fileName, true))
    {
       // Insert other code here. 
    }

La instrucción using proporciona una alternativa recomendada a la típica secuencia .Create, .Save, .Close. Garantiza que se llamará automáticamente al método Dispose (un método interno que Open XML SDK usa para limpiar recursos) cuando se llegue a la llave de cierre. El bloque que sigue a la instrucción using establece un ámbito para el objeto que se crea o se denomina en la instrucción using, en este caso doc. Dado que la clase WordprocessingDocument del SDK de Open XML guarda y cierra automáticamente el objeto como parte de su implementación System.IDisposable y, como Dispose se llama automáticamente al salir del bloque, no es necesario llamar explícitamente a Save y Close─siempre que use.


Estructura de un documento WordProcessingML

La estructura de documento básica de un documento WordProcessingML contiene los elementos document y body, seguidos de uno o varios elementos a nivel de bloque, como p, que representa un párrafo. Un párrafo contiene uno o varios elementos r. La r representa a run (segmento), que es una región de texto con un conjunto de propiedades comunes, como el formato. Un segmento contiene uno o varios elementos t. El elemento t contiene un intervalo de texto. En el siguiente ejemplo de código se muestra el marcado WordprocessingML de un documento que contiene el texto "Example text".

    <w:document xmlns:w="https://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>

Con el SDK de Open XML, puede crear contenido y estructura de documentos mediante clases fuertemente tipadas que corresponden a elementos WordprocessingML . Puede encontrar estas clases en el espacio de nombres DocumentFormat.OpenXml.Wordprocessing . La tabla siguiente muestra los nombres de las clases que corresponden a los elementos document, body, p, r y t.

Elemento de WordprocessingML Open XML SDK (clase) Descripción
documento Document El elemento raíz del elemento de documento principal.
body Body El contenedor de las estructuras a nivel de bloque, como párrafos, tablas, anotaciones y otras recogidas en la especificación ISO/IEC 29500.
p Paragraph Un párrafo.
r Run Un segmento.
t Text Un intervalo de texto.

Estructura del elemento Vanish

El elemento vanish desempeña un papel importante ya que oculta el texto en un archivo de Word. La propiedad de formato Hidden es una propiedad de alternancia, lo que significa que su comportamiento es diferente al usarla dentro de una definición de estilo o al usarla como formato directo. Cuando se usa como parte de una definición de estilo, al establecer esta propiedad se alterna su estado actual. Al establecerla en false (o un equivalente), la configuración actual no cambia. No obstante, cuando se usa como formato directo, al establecerla en true o false, se establece el estado absoluto de la propiedad resultante.

La siguiente información de la especificación ISO/IEC 29500 presenta el elemento vanish.

vanish (Texto oculto)

Este elemento especifica si el contenido de este segmento debe ocultarse en la visualización de un documento. [Nota: la configuración debería afectar a la visualización normal del texto, pero es posible que una aplicación tenga valores de configuración para forzar la visualización del texto oculto. Fin de la nota]

Esta propiedad de formato es una propiedad de alternancia (§17.7.3).

Si este elemento no existe, el valor predeterminado es dejar el formato aplicado en el nivel anterior de la jerarquía de estilos. Si este elemento nunca se aplica en la jerarquía de estilos, el texto no se ocultará al visualizarse en un documento.

[Ejemplo: considere un segmento de texto que debe tener la propiedad de texto oculto activada para el contenido del segmento. Esa restricción se especifica mediante el siguiente WordprocessingML:

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

Este segmento declara que la propiedad vanish se establece para el contenido de este segmento, por lo que dicho contenido se ocultará cuando se visualice el contenido del documento. Fin del ejemplo]

© ISO/IEC29500: 2008.

El siguiente fragmento de esquema XML define el contenido de este elemento.

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

La propiedad val del código anterior es un valor binario que se puede activar o desactivar. Si se le establece el valor on, 1 o true, la propiedad se activará. Si se establece el valor off, 0 o false, la propiedad se desactivará.


Código de ejemplo

En el siguiente ejemplo de código se muestra cómo quitar todo el texto oculto de un documento. Puede llamar al método WDDeleteHiddenText mediante la siguiente llamada como ejemplo para eliminar el texto oculto de un archivo llamado "Word14.docx".

    string docName = @"C:\Users\Public\Documents\Word14.docx";
    WDDeleteHiddenText(docName);

Nota:

[!NOTA] En este ejemplo se supone que el archivo Word14.docx contiene texto oculto. Para ocultar parte del texto del archivo, selecciónelo y haga clic en CTRL+D para mostrar el cuadro de diálogo Fuente. Active la casilla de verificación Oculto y haga clic en Aceptar.

A continuación se incluye el código de ejemplo completo en C# y Visual Basic.

using DocumentFormat.OpenXml.Packaging;
using System;
using System.IO;
using System.Xml;

WDDeleteHiddenText(args[0]);

static void WDDeleteHiddenText(string docName)
{
    // Given a document name, delete all the hidden text.
    const string wordmlNamespace = "https://schemas.openxmlformats.org/wordprocessingml/2006/main";

    using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(docName, true))
    {
        // Manage namespaces to perform XPath queries.
        NameTable nt = new NameTable();
        XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
        nsManager.AddNamespace("w", wordmlNamespace);

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

        // Get the document part from the package.
        // Load the XML in the document part into an XmlDocument instance.
        XmlDocument xdoc = new XmlDocument(nt);
        using (Stream stream = wdDoc.MainDocumentPart.GetStream())
        {
            xdoc.Load(stream);
            XmlNodeList? hiddenNodes = xdoc.SelectNodes("//w:vanish", nsManager);

            if (hiddenNodes is null)
            {
                return;  // No hidden text.
            }

            foreach (System.Xml.XmlNode hiddenNode in hiddenNodes)
            {
                if (hiddenNode.ParentNode is null || hiddenNode.ParentNode.ParentNode is null || hiddenNode.ParentNode.ParentNode.ParentNode is null)
                {
                    continue;
                }

                XmlNode topNode = hiddenNode.ParentNode.ParentNode;
                XmlNode topParentNode = topNode.ParentNode;
                topParentNode.RemoveChild(topNode);

                if (topParentNode.ParentNode is null)
                {
                    continue;
                }

                if (!topParentNode.HasChildNodes)
                {
                    topParentNode.ParentNode.RemoveChild(topParentNode);
                }
            }
        }

        using (Stream stream2 = wdDoc.MainDocumentPart.GetStream(FileMode.Create, FileAccess.Write))
        {
            // Save the document XML back to its document part.
            xdoc.Save(stream2);
        }
    }
}

Vea también