C# ile MS Word Belgelerinden Metin Çıkarma

Word belgelerinden metin çıkarma genellikle farklı senaryolarda gerçekleştirilir. Örneğin, metni analiz etmek, bir belgenin belirli bölümlerini çıkarmak ve bunları tek bir belgede birleştirmek vb. Bu makalede, C# ile Word belgelerinden programlı olarak metin çıkarmayı öğreneceksiniz. Ayrıca, içeriğin paragraflar, tablolar vb. belirli öğeler arasında dinamik olarak nasıl çıkarılacağını ele alacağız.

Word Belgelerinden Metin Çıkarmak için C# Kitaplığı

Aspose.Words for .NET, MS Word belgelerini sıfırdan oluşturmanıza olanak tanıyan güçlü bir kitaplıktır. Ayrıca, mevcut Word belgelerini şifreleme, dönüştürme, metin çıkarma vb. için değiştirmenize olanak tanır. Bu kitaplığı, Word DOCX veya DOC belgelerinden metin çıkarmak için kullanacağız. API’nin DLL’sini indirebilir veya paket yöneticisi konsolunu kullanarak doğrudan NuGet’ten yükleyebilirsiniz.

PM> Install-Package Aspose.Words

C# kullanarak Word Belgelerinde Metin Çıkarma

Bir MS Word belgesi, paragraflar, tablolar, resimler vb. içeren çeşitli öğelerden oluşur. Bu nedenle, metin çıkarma gereksinimleri bir senaryodan diğerine değişebilir. Örneğin, paragraflar, yer imleri, yorumlar vb. arasında metin ayıklamanız gerekebilir.

Bir Word belgesindeki her öğe türü bir düğüm olarak temsil edilir. Bu nedenle, bir belgeyi işlemek için düğümlerle oynamanız gerekecek. Öyleyse başlayalım ve farklı senaryolarda Word belgelerinden nasıl metin çıkarılacağını görelim.

C# dilinde bir Word Belgesinden Metin Çıkarma

Bu bölümde, Word belgeleri için bir C# metin çıkarıcı uygulayacağız ve metin çıkarmanın iş akışı aşağıdaki gibi olacaktır:

  • İlk olarak, metin çıkarma işlemine dahil etmek istediğimiz düğümleri tanımlayacağız.
  • Ardından, belirtilen düğümler arasındaki içeriği çıkaracağız (başlangıç ve bitiş düğümleri dahil veya hariç).
  • Son olarak, örneğin çıkarılan içerikten oluşan yeni bir Word belgesi oluşturmak için çıkarılan düğümlerin klonunu kullanacağız.

Şimdi, metin çıkarımını gerçekleştirmek için düğümleri ve diğer bazı parametreleri geçireceğimiz ExtractContent adında bir yöntem yazalım. Bu yöntem belgeyi ayrıştırır ve düğümleri klonlar. Bu metoda ileteceğimiz parametreler aşağıdadır.

  1. İçeriğin çıkarılması için sırasıyla başlangıç ve bitiş noktaları olarak StartNode ve EndNode. Bunlar hem blok düzeyinde (Paragraf , Tablo) hem de satır içi düzeyde (örn. Çalıştır, FieldStart, BookmarkStart vb.) düğümler olabilir.
    1. Bir alanı geçmek için ilgili FieldStart nesnesini geçmelisiniz.
    2. Yer imlerini geçirmek için BookmarkStart ve BookmarkEnd düğümleri geçilmelidir.
    3. Yorumlar için, CommentRangeStart ve CommentRangeEnd düğümleri kullanılmalıdır.
  2. IsInclusive, belirteçlerin ayıklamaya dahil edilip edilmediğini tanımlar. Bu seçenek false olarak ayarlanırsa ve aynı düğüm veya ardışık düğümler geçirilirse boş bir liste döndürülür.

Aşağıda, iletilen düğümler arasındaki içeriği çıkaran ExtractContent yönteminin tam uygulaması yer almaktadır.

public static ArrayList ExtractContent(Node startNode, Node endNode, bool isInclusive)
{
    // Öncelikle bu metoda iletilen düğümlerin kullanım için geçerli olup olmadığını kontrol edin.
    VerifyParameterNodes(startNode, endNode);

    // Ayıklanan düğümleri depolamak için bir liste oluşturun.
    ArrayList nodes = new ArrayList();

    // Gerekirse işaretçi düğümleri ayırabilmemiz için bu yönteme iletilen orijinal düğümlerin kaydını tutun.
    Node originalStartNode = startNode;
    Node originalEndNode = endNode;

    // Blok düzeyinde düğümlere (paragraflar ve tablolar) dayalı olarak içeriği ayıklayın. Onları bulmak için üst düğümler arasında dolaşın.
    // İşaretleyici düğümlerin satır içi olup olmadığına bağlı olarak ilk ve son düğümlerin içeriğini böleceğiz
    while (startNode.ParentNode.NodeType != NodeType.Body)
        startNode = startNode.ParentNode;

    while (endNode.ParentNode.NodeType != NodeType.Body)
        endNode = endNode.ParentNode;

    bool isExtracting = true;
    bool isStartingNode = true;
    bool isEndingNode = false;
    // Belgeden çıkardığımız geçerli düğüm.
    Node currNode = startNode;

    // İçeriği çıkarmaya başlayın. Tüm blok seviyesindeki düğümleri işleyin ve paragraf biçimlendirmesinin korunması için gerektiğinde özellikle ilk ve son düğümleri ayırın.
    // Yöntem, normal bir çıkarıcıdan biraz daha karmaşıktır, çünkü gerçekten kullanışlı hale getirmek için satır içi düğümleri, alanları, yer imlerini vb. kullanarak ayıklamayı hesaba katmamız gerekir.
    while (isExtracting)
    {
        // Bir kopya elde etmek için geçerli düğümü ve alt öğelerini klonlayın.
        Node cloneNode = currNode.Clone(true);
        isEndingNode = currNode.Equals(endNode);

        if ((isStartingNode || isEndingNode) && cloneNode.IsComposite)
        {
            // Her işaretçiyi ayrı ayrı işlememiz gerekiyor, bu yüzden onu ayrı bir yönteme aktarın.
            if (isStartingNode)
            {
                ProcessMarker((CompositeNode)cloneNode, nodes, originalStartNode, isInclusive, isStartingNode, isEndingNode);
                isStartingNode = false;
            }

            // Koşullu, blok düzeyi başlangıç ve bitiş işaretleri aynı düğüm olabileceğinden ayrı olması gerekir.
            if (isEndingNode)
            {
                ProcessMarker((CompositeNode)cloneNode, nodes, originalEndNode, isInclusive, isStartingNode, isEndingNode);
                isExtracting = false;
            }
        }
        else
            // Düğüm bir başlangıç veya bitiş işaretçisi değildir, kopyayı listeye eklemeniz yeterlidir.
            nodes.Add(cloneNode);

        // Bir sonraki düğüme geçin ve ayıklayın. Bir sonraki düğüm boşsa, bu, içeriğin geri kalanının farklı bir bölümde bulunduğu anlamına gelir.
        if (currNode.NextSibling == null && isExtracting)
        {
            // Sonraki bölüme geçin.
            Section nextSection = (Section)currNode.GetAncestor(NodeType.Section).NextSibling;
            currNode = nextSection.Body.FirstChild;
        }
        else
        {
            // Vücuttaki bir sonraki düğüme git.
            currNode = currNode.NextSibling;
        }
    }

    // Düğüm işaretçileri arasındaki düğümleri döndürün.
    return nodes;
}

Metin çıkarma işlemini gerçekleştirmek için ExtractContent yöntemi tarafından aşağıda verilen bazı yardımcı yöntemler de gereklidir.

public static List<Paragraph> ParagraphsByStyleName(Document doc, string styleName)
{
    // Belirtilen stildeki paragrafları toplamak için bir dizi oluşturun.
    List<Paragraph> paragraphsWithStyle = new List<Paragraph>();

    NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);

    // Belirtilen stile sahip olanları bulmak için tüm paragraflara bakın.
    foreach (Paragraph paragraph in paragraphs)
    {
        if (paragraph.ParagraphFormat.Style.Name == styleName)
            paragraphsWithStyle.Add(paragraph);
    }

    return paragraphsWithStyle;
}
private static void VerifyParameterNodes(Node startNode, Node endNode)
{
    // Bu kontrollerin yapılma sırası önemlidir.
    if (startNode == null)
        throw new ArgumentException("Start node cannot be null");
    if (endNode == null)
        throw new ArgumentException("End node cannot be null");

    if (!startNode.Document.Equals(endNode.Document))
        throw new ArgumentException("Start node and end node must belong to the same document");

    if (startNode.GetAncestor(NodeType.Body) == null || endNode.GetAncestor(NodeType.Body) == null)
        throw new ArgumentException("Start node and end node must be a child or descendant of a body");

    // Bitiş düğümünün, DOM ağacındaki başlangıç düğümünden sonra olduğunu kontrol edin
    // Önce farklı bölümlerde olup olmadıklarını kontrol edin, sonra değillerse bulundukları bölümün gövdesindeki konumlarını kontrol edin.
    Section startSection = (Section)startNode.GetAncestor(NodeType.Section);
    Section endSection = (Section)endNode.GetAncestor(NodeType.Section);

    int startIndex = startSection.ParentNode.IndexOf(startSection);
    int endIndex = endSection.ParentNode.IndexOf(endSection);

    if (startIndex == endIndex)
    {
        if (startSection.Body.IndexOf(startNode) > endSection.Body.IndexOf(endNode))
            throw new ArgumentException("The end node must be after the start node in the body");
    }
    else if (startIndex > endIndex)
        throw new ArgumentException("The section of end node must be after the section start node");
}
private static bool IsInline(Node node)
{
    // Düğümün bir Paragraf veya Tablo düğümünün soyundan olup olmadığını ve ayrıca bir paragraf veya tablo olup olmadığını test edin, bir yorum sınıfı içinde bir paragrafın soyundan gelen bir paragraf mümkündür.
    return ((node.GetAncestor(NodeType.Paragraph) != null || node.GetAncestor(NodeType.Table) != null) && !(node.NodeType == NodeType.Paragraph || node.NodeType == NodeType.Table));
}
private static void ProcessMarker(CompositeNode cloneNode, ArrayList nodes, Node node, bool isInclusive, bool isStartMarker, bool isEndMarker)
{
    // Blok seviyesinde bir düğümle uğraşıyorsak, sadece dahil edilmesi gerekip gerekmediğine bakın ve onu listeye ekleyin.
    if (!IsInline(node))
    {
        // İşaretçiler aynı düğüm ise, düğümü iki kez eklemeyin
        if (!(isStartMarker && isEndMarker))
        {
            if (isInclusive)
                nodes.Add(cloneNode);
        }
        return;
    }

    // Bir işaretçi bir FieldStart düğümüyse, dahil edilip edilmeyeceğini kontrol edin.
    // Basit olması için FieldStart ve FieldEnd'in aynı paragrafta göründüğünü varsayıyoruz.
    if (node.NodeType == NodeType.FieldStart)
    {
        // İşaretçi bir başlangıç düğümüyse ve dahil edilmemişse, alanın sonuna atlayın.
        // İşaretçi bir bitiş düğümüyse ve dahil edilecekse, alanın kaldırılmaması için bitiş alanına gidin.
        if ((isStartMarker && !isInclusive) || (!isStartMarker && isInclusive))
        {
            while (node.NextSibling != null && node.NodeType != NodeType.FieldEnd)
                node = node.NextSibling;

        }
    }

    // İşaretçilerden herhangi biri bir yorumun parçasıysa, yorumun kendisini dahil etmek için işaretçiyi Yorum'a doğru ileri götürmemiz gerekir.
    // CommentRangeEnd düğümünden sonra bulunan düğüm.
    if (node.NodeType == NodeType.CommentRangeEnd)
    {
        while (node.NextSibling != null && node.NodeType != NodeType.Comment)
            node = node.NextSibling;

    }

    // Klonlanmış düğümümüzde karşılık gelen düğümü dizine göre bulun ve döndürün.
    // Başlangıç ve bitiş düğümü aynıysa, bazı alt düğümler zaten kaldırılmış olabilir. Çıkar
    // Doğru dizini elde etmek için fark.
    int indexDiff = node.ParentNode.ChildNodes.Count - cloneNode.ChildNodes.Count;

    // Alt düğüm sayısı aynı.
    if (indexDiff == 0)
        node = cloneNode.ChildNodes[node.ParentNode.IndexOf(node)];
    else
        node = cloneNode.ChildNodes[node.ParentNode.IndexOf(node) - indexDiff];

    // İşaretçiye kadar olan/işaretleyiciden düğümleri kaldırın.
    bool isSkip = false;
    bool isProcessing = true;
    bool isRemoving = isStartMarker;
    Node nextNode = cloneNode.FirstChild;

    while (isProcessing && nextNode != null)
    {
        Node currentNode = nextNode;
        isSkip = false;

        if (currentNode.Equals(node))
        {
            if (isStartMarker)
            {
                isProcessing = false;
                if (isInclusive)
                    isRemoving = false;
            }
            else
            {
                isRemoving = true;
                if (isInclusive)
                    isSkip = true;
            }
        }

        nextNode = nextNode.NextSibling;
        if (isRemoving && !isSkip)
            currentNode.Remove();
    }

    // İşlemden sonra bileşik düğüm boş olabilir. Varsa dahil etmeyin.
    if (!(isStartMarker && isEndMarker))
    {
        if (cloneNode.HasChildNodes)
            nodes.Add(cloneNode);
    }

}
public static Document GenerateDocument(Document srcDoc, ArrayList nodes)
{
    // Boş bir belge oluşturun.
    Document dstDoc = new Document();
    // İlk paragrafı boş belgeden çıkarın.
    dstDoc.FirstSection.Body.RemoveAllChildren();

    // Listedeki her düğümü yeni belgeye aktarın. Düğümün orijinal biçimlendirmesini koruyun.
    NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KeepSourceFormatting);

    foreach (Node node in nodes)
    {
        Node importNode = importer.ImportNode(node, true);
        dstDoc.FirstSection.Body.AppendChild(importNode);
    }

    // Oluşturulan belgeyi iade edin.
    return dstDoc;
}

Artık bu yöntemleri kullanmaya ve bir Word belgesinden metin çıkarmaya hazırız.

Bir Word Belgesindeki Paragraflar Arasındaki Metni Çıkarma

Bir Word DOCX belgesinde iki paragraf arasındaki içeriğin nasıl çıkarılacağını görelim. C# dilinde bu işlemi gerçekleştirme adımları aşağıdadır.

  • İlk olarak, Document sınıfını kullanarak Word belgesini yükleyin.
  • Document.FirstSection.Body.GetChild(NodeType.PARAGRAPH, int, boolean) yöntemini kullanarak başlangıç ve bitiş paragraflarının referansını iki nesneye alın.
  • Düğümleri bir nesneye ayıklamak için ExtractContent(startPara, endPara, True) yöntemini çağırın.
  • Ayıklanan içerikten oluşan belge oluşturmak için GenerateDocument(Document, extractedNodes) yardımcı yöntemini çağırın.
  • Son olarak, Document.Save(string) yöntemini kullanarak döndürülen belgeyi kaydedin.

Aşağıdaki kod örneği, C# dilinde bir Word belgesinde 7. ve 11. paragraflar arasındaki metnin nasıl ayıklanacağını gösterir.

// Word belgesini yükle
Document doc = new Document("document.docx");

// Düğümleri toplayın (GetChild yöntemi 0 tabanlı dizin kullanır)
Paragraph startPara = (Paragraph)doc.FirstSection.Body.GetChild(NodeType.Paragraph, 6, true);
Paragraph endPara = (Paragraph)doc.FirstSection.Body.GetChild(NodeType.Paragraph, 10, true);

// Belgedeki bu düğümler arasındaki içeriği çıkarın. Bu işaretleri ekstraksiyona dahil edin.
ArrayList extractedNodes = ExtractContent(startPara, endPara, true);

// İçeriği yeni bir belgeye ekleyin ve diske kaydedin.
Document dstDoc = GenerateDocument(doc, extractedNodes);
dstDoc.Save("output.docx");

Bir Word Belgesinde Farklı Düğüm Türleri Arasında Metin Çıkarma

Farklı düğüm türleri arasında da içerik çıkarabilirsiniz. Gösterim için, bir paragraf ve bir tablo arasındaki içeriği çıkaralım ve yeni bir Word belgesine kaydedelim. Aşağıda bu işlemi gerçekleştirmek için adımlar verilmiştir.

  • Document sınıfını kullanarak Word belgesini yükleyin.
  • Document.FirstSection.Body.GetChild(NodeType, int, boolean) yöntemini kullanarak başlangıç ve bitiş düğümlerinin referansını iki nesneye alın.
  • Düğümleri bir nesneye ayıklamak için ExtractContent(startPara, endPara, True) yöntemini çağırın.
  • Ayıklanan içerikten oluşan belge oluşturmak için GenerateDocument(Document, extractedNodes) yardımcı yöntemini çağırın.
  • Döndürülen belgeyi Document.Save(string) yöntemini kullanarak kaydedin.

Aşağıdaki kod örneği, C# dilinde bir paragraf ile bir tablo arasındaki metnin nasıl ayıklanacağını gösterir.

// Word belgesini yükle
Document doc = new Document("document.docx");

Paragraph startPara = (Paragraph)doc.LastSection.GetChild(NodeType.Paragraph, 2, true);
Table endTable = (Table)doc.LastSection.GetChild(NodeType.Table, 0, true);

// Belgedeki bu düğümler arasındaki içeriği çıkarın. Bu işaretleri ekstraksiyona dahil edin.
ArrayList extractedNodes = ExtractContent(startPara, endTable, true);

// İçeriği yeni bir belgeye ekleyin ve diske kaydedin.
Document dstDoc = GenerateDocument(doc, extractedNodes);
dstDoc.Save("output.docx");

Stillere Göre Paragraflar Arasındaki Metni Çıkarın

Şimdi, stillere göre paragraflar arasında nasıl içerik çıkarılacağını kontrol edelim. Gösterim için, Word belgesindeki ilk “Başlık 1” ile ilk “Başlık 3” arasındaki içeriği çıkaracağız. Aşağıdaki adımlar, bunun C# dilinde nasıl elde edileceğini göstermektedir.

  • İlk olarak, Document sınıfını kullanarak Word belgesini yükleyin.
  • Ardından, ParagraphsByStyleName(Document, “Heading 1”) yardımcı yöntemini kullanarak paragrafları bir nesneye çıkarın.
  • ParagraphsByStyleName(Document, “Heading 3”) yardımcı yöntemini kullanarak paragrafları başka bir nesneye çıkarın.
  • ExtractContent(startPara, endPara, True) yöntemini çağırın ve her iki paragraf dizisindeki ilk öğeleri birinci ve ikinci parametreler olarak iletin.
  • Ayıklanan içerikten oluşan belge oluşturmak için GenerateDocument(Document, extractedNodes) yardımcı yöntemini çağırın.
  • Son olarak, Document.Save(string) yöntemini kullanarak döndürülen belgeyi kaydedin.

Aşağıdaki kod örneği, stilleri temel alan paragraflar arasında içeriğin nasıl ayıklanacağını gösterir.

// Word belgesini yükle
Document doc = new Document("document.docx");

// İlgili başlık stillerini kullanarak paragrafların bir listesini toplayın.
List<Paragraph> parasStyleHeading1 = ParagraphsByStyleName(doc, "Heading 1");
List<Paragraph> parasStyleHeading3 = ParagraphsByStyleName(doc, "Heading 3");

// Bu stillerle paragrafların ilk örneğini kullanın.
Node startPara1 = (Node)parasStyleHeading1[0];
Node endPara1 = (Node)parasStyleHeading3[0];

// Belgedeki bu düğümler arasındaki içeriği çıkarın. Bu işaretleri ekstraksiyona dahil etmeyin.
ArrayList extractedNodes = ExtractContent(startPara1, endPara1, false);

// İçeriği yeni bir belgeye ekleyin ve diske kaydedin.
Document dstDoc = GenerateDocument(doc, extractedNodes);
dstDoc.Save("output.docx");

Devamını oku

Bu belgeleme makalesini kullanarak Word belgelerinden metin ayıklamanın diğer senaryolarını keşfedebilirsiniz.

Ücretsiz API Lisansı Alın

Aspose.Words for .NET’i değerlendirme sınırlamaları olmaksızın kullanmak için bir geçici lisans alabilirsiniz.

Çözüm

Bu makalede, C# kullanarak MS Word belgelerinden metin çıkarmayı öğrendiniz. Ayrıca, bir Word belgesindeki benzer veya farklı düğüm türleri arasında programlı olarak nasıl içerik çıkarılacağını gördünüz. Böylece, kendi MS Word metin çıkarıcınızı C# dilinde oluşturabilirsiniz. Ayrıca, dokümantasyonu kullanarak Aspose.Words for .NET’in diğer özelliklerini keşfedebilirsiniz. Herhangi bir sorunuz olması durumunda forumumuz aracılığıyla bize bildirmekten çekinmeyin.

Ayrıca bakınız

İpucu: Aspose PowerPoint to Word Converter’ı kontrol etmek isteyebilirsiniz çünkü popüler sunumu Word belgesine dönüştürme sürecini gösterir.