💡 דוגמה מלאה עובדת זמינה ב‑GitHub:
parse-docx-to-markdown-chunks-dotnet

הדרך הישנה הייתה כואבת

חילוק Markdown מבוסס כותרות הוא נתיב הכנה לשאיבת מידע ב‑.NET שממיר קבצי Office ו‑PDF לטקסט בגודל של קטעים לפני ההטמעה. ללא זה, צוותים לעיתים קרובות מזרים קובץ Word שלם לווקטור יחיד. פסקת הכיסוי וסעיף החובה חולקים הטמעה אחת, ולכן חיפוש קוסינוס מדרג את הקטע הלא נכון. נתקלתי בזה במדריך פנימי של שלוש עמודים: כל שאילתה שלפה תחילה את בלוק הכותרת מכיוון שהאינדקס מעולם לא ראה את המבנה # / ## שהמחברים כבר כתבו.

יצירת ממיר DOCX‑ל‑Markdown באופן ידני דורשת הליכה בסגנונות Open XML, מיפוי רמות רשימות, ובכל זאת נכשלת כאשר ההעלאה הבאה היא PDF שהנתיב של Markdown המפורמט מחזיר null. חלונות טוקן בגודל קבוע מתעלמים מהכותרות האלה. קורפוסים של לילה ערבבנים קונכיות ריקות עם מדריכים ענקיים מכיוון שאף אחד לא סינן לפי מספר עמודים או גודל תחילה.

העלות האמיתית של הטמעות של קובץ שלם: תשובות מקטעים שגויים, בזבוז משאבי חילוץ על העלאות זבל, ואין קבצי chunk-01.md שהמפעילים יכולים לפתוח במהלך אצווה רעה.

יש דרך טובה יותר

GroupDocs.Parser for .NET מחליף את הבלגן הזה בארבע קריאות ממוקדות: GetDocumentInfo, GetFormattedText(FormattedTextMode.Markdown), GetText כאשר Markdown הוא null, ומטייל כותרות קטן שכותב chunk‑NN.md. סוג ה‑Parser זהה מכסה ניתוח Word DOCX ונפילת טקסט PDF, כך שאתה שומר על נתיב שירות C# אחד.

תזדקק ל‑:

  • .NET 8 SDK
  • GroupDocs.Parser 26.10.0 (רישיון זמני)
  • קובץ Word DOCX (הדוגמה היא 3 עמודים / 14820 בתים) ובחירה קובץ PDF
dotnet add package GroupDocs.Parser --version 26.10.0

הדרך החדשה: בדיקה, חילוץ, חזרה, פיצול

הנה אותה הכנה לשאיבה אחרי המעבר. הדוגמה בקונסול תחת parse-docx-to-markdown-chunks-dotnet כותבת מידע, Markdown, טקסט PDF, ו‑ארבעה קטעי כותרת עבור ה‑DOCX המסופק.

שלב 1 - סינון עם GetDocumentInfo

בקש את סוג הקובץ, מספר העמודים והגודל לפני שאתה משלם על חילוץ מלא.

using var parser = new Parser(sourcePath);
var info = parser.GetDocumentInfo();

var sb = new StringBuilder();
sb.AppendLine($"Source: {Path.GetFileName(sourcePath)}");
sb.AppendLine($"File type: {info?.FileType}");
sb.AppendLine($"Pages: {info?.PageCount}");
sb.AppendLine($"Size: {info?.Size} bytes");
File.WriteAllText(outputPath, sb.ToString());

תעד את העובדות לצד מזהה העבודה. בדוגמת ה‑DOCX תראה Microsoft Word Open XML Document, 3 עמודים, ו‑14820 בתים.

שלב 2 - העדפת Markdown מ‑GetFormattedText

עבור Word ופורמטים שתומכים בחילוץ מפורמט, שמור על כותרות ATX עבור המחלק.

using var parser = new Parser(sourcePath);
using TextReader? reader = parser.GetFormattedText(
    new FormattedTextOptions(FormattedTextMode.Markdown));

if (reader == null)
{
    return null;
}

string markdown = reader.ReadToEnd();
File.WriteAllText(outputPath, markdown, Encoding.UTF8);
return markdown;

null הוא סימן להחליף נתיבים, לא קריסה. כתוב ב‑UTF‑8 כדי שכלי הקטעים וה‑git diffs יישארו קריאים.

שלב 3 - חזרה עם GetText עבור PDF

כאשר מצב Markdown מחזיר null, שמור את הקובץ בצינור עם שכבת טקסט פשוטה.

using var parser = new Parser(sourcePath);
using TextReader? reader = parser.GetText();
if (reader == null)
{
    return null;
}

string text = reader.ReadToEnd();
File.WriteAllText(outputPath, text, Encoding.UTF8);
return text;

צפה בקובץ .txt, ולא בכותרות # שהומצאו. המארח בדוגמה כותב Result/sample-pdf.txt עבור ענף ה‑PDF.

שלב 4 - פיצול Markdown על # ו‑##

הולך שורות; מרוקן כאשר מופיעה כותרת ATX חדשה # או ##; כותב chunk‑NN.md.

var chunks = new List<string>();
var current = new StringBuilder();
using (var reader = new StringReader(markdown))
{
    string? line;
    while ((line = reader.ReadLine()) != null)
    {
        bool isHeading = line.StartsWith("# ", StringComparison.Ordinal)
            || line.StartsWith("## ", StringComparison.Ordinal);
        if (isHeading && current.Length > 0)
        {
            chunks.Add(current.ToString().TrimEnd());
            current.Clear();
        }
        current.AppendLine(line);
    }
}

מחק קבצי chunk-*.md ישנים תחילה. שורות ### עמוקות נשארות בתוך הקטע הנוכחי. ה‑DOCX בדוגמה מניב ארבעה קבצים תחת Result/chunks/.

מתי עליי להחליף הטמעות של קובץ שלם בנתיב הזה?

החלף הטמעות של קובץ שלם כאשר הקליטה מערבבת Word DOCX ו‑PDF והאינדקס זקוק ל‑Markdown בגודל קטעים. הפעל תחילה GetDocumentInfo, נסה Markdown עבור קבצי Office, קרא GetText כאשר הקורא המפורמט הוא null, ופצל רק כאשר קיימים סמני # / ##. השאר טקסט PDF לא מובנה במצבו עד שתוסיף מדיניות קטעים נפרדת. סדר זה תואם לאפליקציית הקונסול בדוגמה ומשאיר מצבי כשל ברורים למפעילים.

מה השתנה למפעילים

לפני אחרי
הטמעה אחת לכל קובץ הטמעה אחת לכל קטע כותרת
Markdown מותאם Open XML מצב Markdown של GetFormattedText
PDF נזרק כאשר הקורא המפורמט הוא null GetText כותב קובץ טקסט
אין בדיקה מקדימה זולה בדיקת מספר עמודים וגודל

הקפד לשחרר כל Parser ו‑TextReader. החל רישיון או רישיון זמני לפני נפח לילה. התייחס להעלאות כקלט בלתי מהימן ונתח במעבד מבודד.

נסה זאת על הקבצים שלך

שכפל את parse-docx-to-markdown-chunks-dotnet, שחזר GroupDocs.Parser 26.10.0, והפעל נגד documents/sample.docx. לאחר מכן הפנה את ארבעת השיטות לאחד המדריכים שלך ופתח את קבצי chunk-*.md שנוצרו.