💡 ตัวอย่างทำงานเต็มที่พร้อมบน GitHub:
parse-docx-to-markdown-chunks-dotnet

วิธีเก่าเคยทำให้เจ็บปวด

การแบ่งส่วน Markdown ตามหัวเรื่องเป็นกระบวนการเตรียมข้อมูลดึงข้อมูลใน .NET ที่แปลงไฟล์ Office และ PDF ให้เป็นข้อความขนาดส่วนก่อนที่คุณจะฝัง หากไม่มีขั้นตอนนี้ ทีมมักจะใส่ไฟล์ Word ทั้งหมดลงในเวกเตอร์เดียว ย่อหน้าปกและข้อกำหนดหน้าที่จะแบ่งปันการฝังเดียวกัน ทำให้การค้นหาแบบ cosine ให้ผลลัพธ์ส่วนที่ผิด ฉันเจอปัญหานี้ในคู่มือภายในสามหน้า: ทุกคำถามดึงบล็อกหัวเรื่องแรกก่อน เพราะดัชนีไม่เคยเห็นโครงสร้าง # / ## ที่ผู้เขียนได้เขียนไว้แล้ว

การสร้างตัวแปลง DOCX‑to‑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 (temporary license)
  • ไฟล์ 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());

บันทึกข้อเท็จจริงเหล่านี้พร้อมกับ job id บน 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 diff อ่านได้

ขั้นตอนที่ 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 ที่ไม่มีโครงสร้างไว้จนกว่าจะเพิ่มนโยบายการแบ่งส่วนแยกต่างหาก ลำดับนี้ตรงกับแอปคอนโซลตัวอย่างและทำให้โหมดความล้มเหลวชัดเจนสำหรับผู้ปฏิบัติการ

สิ่งที่เปลี่ยนแปลงสำหรับผู้ปฏิบัติการ

ก่อน หลัง
การฝังหนึ่งครั้งต่อไฟล์ การฝังหนึ่งครั้งต่อบล็อกหัวเรื่อง
Open XML Markdown ที่กำหนดเอง โหมด Markdown ของ GetFormattedText
PDF ถูกละทิ้งเมื่อรีดเดอร์จัดรูปแบบเป็น null GetText เขียนไฟล์ข้อความ
ไม่มีการตรวจสอบล่วงหน้าแบบราคาถูก การตรวจสอบจำนวนหน้าและขนาดทำงานเป็นเกต

ทำลาย (Dispose) ทุก Parser และ TextReader ใช้ไลเซนส์หรือ temporary license ก่อนปริมาณงานข้ามคืน ปฏิบัติกับการอัปโหลดเป็นอินพุตที่ไม่เชื่อถือและแยกการประมวลผลใน worker แยก

ลองใช้กับไฟล์ของคุณเอง

โคลน parse-docx-to-markdown-chunks-dotnet, รีสโตร์ GroupDocs.Parser 26.10.0, และรันกับ documents/sample.docx จากนั้นชี้เมธอดสี่ตัวเดียวกันไปยังคู่มือของคุณและเปิดไฟล์ chunk-*.md ที่สร้างขึ้น