แยกเนื้อหาระหว่างโหนดในเอกสาร
เมื่อทำงานกับเอกสาร สิ่งสำคัญคือต้องสามารถดึงเนื้อหาจากช่วงเฉพาะภายในเอกสารได้อย่างง่ายดาย อย่างไรก็ตาม เนื้อหาอาจประกอบด้วยองค์ประกอบที่ซับซ้อน เช่น ย่อหน้า ตาราง รูปภาพ ฯลฯ
ไม่ว่าเนื้อหาใดจะต้องถูกแยกออกมา วิธีการแยกเนื้อหานั้นจะถูกกำหนดโดยโหนดใดที่ถูกเลือกเพื่อแยกเนื้อหาระหว่างนั้นเสมอ สิ่งเหล่านี้อาจเป็นเนื้อหาข้อความทั้งหมดหรือการเรียกใช้ข้อความธรรมดา
มีสถานการณ์ที่เป็นไปได้มากมาย ดังนั้นโหนดประเภทต่างๆ มากมายที่ต้องพิจารณาเมื่อแยกเนื้อหา ตัวอย่างเช่น คุณอาจต้องการแยกเนื้อหาระหว่าง:
- สองย่อหน้าเฉพาะ
- การเรียกใช้ข้อความเฉพาะ
- ช่องประเภทต่างๆ เช่น ช่องรวม
- ช่วงเริ่มต้นและสิ้นสุดของบุ๊กมาร์กหรือความคิดเห็น
- เนื้อหาข้อความต่าง ๆ ที่อยู่ในส่วนแยกกัน
ในบางสถานการณ์ คุณอาจต้องรวมประเภทโหนดที่แตกต่างกัน เช่น แยกเนื้อหาระหว่างย่อหน้าและช่อง หรือระหว่างการเรียกใช้และบุ๊กมาร์ก
บทความนี้ให้ข้อมูลการใช้งานโค้ดสำหรับการแยกข้อความระหว่างโหนดต่างๆ รวมถึงตัวอย่างของสถานการณ์ทั่วไป
ทำไมต้องแยกเนื้อหา
บ่อยครั้งที่เป้าหมายในการแยกเนื้อหาคือการทำซ้ำหรือบันทึกแยกกันในเอกสารใหม่ ตัวอย่างเช่น คุณสามารถแยกเนื้อหาและ:
- คัดลอกลงในเอกสารแยกต่างหาก
- แปลงส่วนเฉพาะของเอกสารเป็น PDF หรือรูปภาพ
- ทำซ้ำเนื้อหาในเอกสารหลายครั้ง
- ทำงานกับเนื้อหาที่แยกออกจากส่วนที่เหลือของเอกสาร
ซึ่งสามารถทำได้ง่ายๆ โดยใช้ Aspose.Words และการติดตั้งโค้ดด้านล่าง
การแยกอัลกอริทึมเนื้อหา
รหัสในส่วนนี้กล่าวถึงสถานการณ์ที่เป็นไปได้ทั้งหมดที่อธิบายไว้ข้างต้นด้วยวิธีทั่วไปและนำมาใช้ซ้ำได้วิธีเดียว โครงร่างทั่วไปของเทคนิคนี้เกี่ยวข้องกับ:
- รวบรวมโหนดที่กำหนดพื้นที่ของเนื้อหาที่จะแยกออกจากเอกสารของคุณ ผู้ใช้จะจัดการการดึงโหนดเหล่านี้ในโค้ดของพวกเขา โดยขึ้นอยู่กับสิ่งที่พวกเขาต้องการแยกออก
- การส่งโหนดเหล่านี้ไปยังวิธี ExtractContent ที่ระบุไว้ด้านล่าง คุณต้องส่งพารามิเตอร์บูลีนซึ่งระบุว่าโหนดเหล่านี้ซึ่งทำหน้าที่เป็นเครื่องหมาย ควรรวมอยู่ในการแยกข้อมูลหรือไม่
- การดึงรายการเนื้อหาที่โคลน (โหนดที่คัดลอก) ที่ระบุให้แยกออก คุณสามารถใช้รายการโหนดนี้ในลักษณะที่เกี่ยวข้องได้ เช่น การสร้างเอกสารใหม่ที่มีเฉพาะเนื้อหาที่เลือก
วิธีแยกเนื้อหา
หากต้องการแยกเนื้อหาออกจากเอกสารของคุณ คุณต้องเรียกใช้เมธอด ExtractContent ด้านล่างและส่งพารามิเตอร์ที่เหมาะสม พื้นฐานพื้นฐานของวิธีนี้เกี่ยวข้องกับการค้นหาโหนดระดับบล็อก (ย่อหน้าและตาราง) และทำการโคลนเพื่อสร้างสำเนาที่เหมือนกัน หากโหนดเครื่องหมายที่ส่งผ่านเป็นระดับบล็อก วิธีการก็สามารถคัดลอกเนื้อหาในระดับนั้นและเพิ่มลงในอาร์เรย์ได้
อย่างไรก็ตาม หากโหนดมาร์กเกอร์เป็นแบบอินไลน์ (ลูกของย่อหน้า) สถานการณ์จะซับซ้อนมากขึ้น เนื่องจากจำเป็นต้องแยกย่อหน้าที่โหนดอินไลน์ ไม่ว่าจะเป็นการรัน ฟิลด์บุ๊กมาร์ก ฯลฯ เนื้อหาในโหนดพาเรนต์ที่ถูกโคลนไม่ ที่อยู่ระหว่างเครื่องหมายจะถูกลบออก กระบวนการนี้ใช้เพื่อให้แน่ใจว่าโหนดแบบอินไลน์จะยังคงรูปแบบของย่อหน้าหลักไว้ วิธีการนี้จะเรียกใช้การตรวจสอบโหนดที่ส่งผ่านเป็นพารามิเตอร์และส่งข้อยกเว้นหากโหนดใดโหนดหนึ่งไม่ถูกต้อง พารามิเตอร์ที่จะส่งไปยังวิธีนี้คือ:
- StartNode และ EndNode พารามิเตอร์สองตัวแรกคือโหนดที่กำหนดว่าการแยกเนื้อหาจะเริ่มต้นและสิ้นสุดที่ใดตามลำดับ โหนดเหล่านี้สามารถเป็นได้ทั้งระดับบล็อก (Paragraph, Table) หรือระดับอินไลน์ (เช่น Run, FieldStart, BookmarkStart ฯลฯ ):
- หากต้องการส่งผ่านฟิลด์ คุณควรส่งออบเจ็กต์ FieldStart ที่เกี่ยวข้อง
- หากต้องการส่งผ่านบุ๊กมาร์ก ควรส่งโหนด BookmarkStart และ BookmarkEnd
- ในการแสดงความคิดเห็น ควรใช้โหนด CommentRangeStart และ CommentRangeEnd
- IsInclusive. กำหนดว่าเครื่องหมายถูกรวมไว้ในการแตกข้อมูลหรือไม่ หากตัวเลือกนี้ถูกตั้งค่าเป็น false และส่งโหนดเดียวกันหรือโหนดต่อเนื่องกัน รายการว่างจะถูกส่งกลับ:
- หากส่งโหนด FieldStart ตัวเลือกนี้จะกำหนดว่าจะรวมหรือยกเว้นฟิลด์ทั้งหมด
- หากส่งผ่านโหนด BookmarkStart หรือ BookmarkEnd ตัวเลือกนี้จะกำหนดว่ารวมบุ๊กมาร์กไว้หรือเพียงเนื้อหาระหว่างช่วงบุ๊กมาร์ก
- หากส่งโหนด CommentRangeStart หรือ CommentRangeEnd ตัวเลือกนี้จะกำหนดว่าจะต้องรวมความคิดเห็นนั้นไว้หรือเพียงเนื้อหาในช่วงความคิดเห็น
การดำเนินการตามวิธี ExtractContent คุณสามารถค้นหา บน Aspose.Words GitHub วิธีการนี้จะอ้างอิงถึงในสถานการณ์สมมติในบทความนี้
นอกจากนี้เรายังจะกำหนดวิธีการแบบกำหนดเองเพื่อสร้างเอกสารจากโหนดที่แยกออกมาได้อย่างง่ายดาย วิธีการนี้ใช้ในหลายสถานการณ์ด้านล่าง และเพียงสร้างเอกสารใหม่และนำเข้าเนื้อหาที่แยกออกมาลงไป
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีนำรายการโหนดและแทรกลงในเอกสารใหม่:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
public static Document GenerateDocument(Document srcDoc, List<Node> nodes) | |
{ | |
Document dstDoc = new Document(); | |
// Remove the first paragraph from the empty document. | |
dstDoc.FirstSection.Body.RemoveAllChildren(); | |
// Import each node from the list into the new document. Keep the original formatting of the node. | |
NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KeepSourceFormatting); | |
foreach (Node node in nodes) | |
{ | |
Node importNode = importer.ImportNode(node, true); | |
dstDoc.FirstSection.Body.AppendChild(importNode); | |
} | |
return dstDoc; | |
} |
แยกเนื้อหาระหว่างย่อหน้า
สิ่งนี้สาธิตวิธีการใช้วิธีการด้านบนเพื่อแยกเนื้อหาระหว่างย่อหน้าเฉพาะ ในกรณีนี้ เราต้องการแยกเนื้อหาของตัวอักษรที่พบในครึ่งแรกของเอกสาร เราบอกได้เลยว่าอยู่ระหว่างย่อหน้าที่ 7 ถึงย่อหน้าที่ 11
รหัสด้านล่างทำให้งานนี้สำเร็จ ย่อหน้าที่เหมาะสมจะถูกแยกออกมาโดยใช้วิธี GetChild ในเอกสารและส่งผ่านดัชนีที่ระบุ จากนั้นเราจะส่งโหนดเหล่านี้ไปยังวิธี ExtractContent และระบุว่าจะต้องรวมสิ่งเหล่านี้ไว้ในการแตกข้อมูล วิธีนี้จะส่งคืนเนื้อหาที่คัดลอกระหว่างโหนดเหล่านี้ซึ่งจะถูกแทรกลงในเอกสารใหม่
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกเนื้อหาระหว่างย่อหน้าเฉพาะโดยใช้วิธี ExtractContent
ด้านบน:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
Paragraph startPara = (Paragraph) doc.FirstSection.Body.GetChild(NodeType.Paragraph, 6, true); | |
Paragraph endPara = (Paragraph) doc.FirstSection.Body.GetChild(NodeType.Paragraph, 10, true); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
List<Node> extractedNodes = ExtractContentHelper.ExtractContent(startPara, endPara, true); | |
Document dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodes); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenParagraphs.docx"); |
แยกเนื้อหาระหว่างโหนดประเภทต่างๆ
เราสามารถแยกเนื้อหาระหว่างการรวมกันของระดับบล็อกหรือโหนดแบบอินไลน์ ในสถานการณ์ด้านล่างนี้ เราจะแยกเนื้อหาระหว่างย่อหน้าแรกและตารางในส่วนที่สองให้ครบถ้วน เราได้รับโหนดเครื่องหมายโดยการเรียกวิธี FirstParagraph และ GetChild บนส่วนที่สองของเอกสารเพื่อดึงข้อมูลโหนด Paragraph และ Table ที่เหมาะสม หากต้องการรูปแบบเล็กน้อย ให้ทำซ้ำเนื้อหาและแทรกไว้ด้านล่างของต้นฉบับแทน
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกเนื้อหาระหว่างย่อหน้าและตารางโดยใช้วิธี ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
Paragraph startPara = (Paragraph) doc.LastSection.GetChild(NodeType.Paragraph, 2, true); | |
Table endTable = (Table) doc.LastSection.GetChild(NodeType.Table, 0, true); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
List<Node> extractedNodes = ExtractContentHelper.ExtractContent(startPara, endTable, true); | |
// Let's reverse the array to make inserting the content back into the document easier. | |
extractedNodes.Reverse(); | |
foreach (Node extractedNode in extractedNodes) | |
endTable.ParentNode.InsertAfter(extractedNode, endTable); | |
doc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenBlockLevelNodes.docx"); |
แยกเนื้อหาระหว่างย่อหน้าตามสไตล์
คุณอาจต้องแยกเนื้อหาระหว่างย่อหน้าที่มีสไตล์เดียวกันหรือต่างกัน เช่น ระหว่างย่อหน้าที่ทำเครื่องหมายด้วยสไตล์หัวเรื่อง รหัสด้านล่างแสดงวิธีการบรรลุเป้าหมายนี้ เป็นตัวอย่างง่ายๆ ซึ่งจะแยกเนื้อหาระหว่างอินสแตนซ์แรกของสไตล์ “ส่วนหัว 1” และ “ส่วนหัว 3” โดยไม่ต้องแยกส่วนหัวด้วย ในการดำเนินการนี้ เราตั้งค่าพารามิเตอร์สุดท้ายเป็น false ซึ่งระบุว่าไม่ควรรวมโหนดเครื่องหมายไว้ด้วย
ในการใช้งานที่เหมาะสม ควรรันแบบวนซ้ำเพื่อแยกเนื้อหาระหว่างย่อหน้าทั้งหมดของสไตล์เหล่านี้ออกจากเอกสาร เนื้อหาที่แยกออกมาจะถูกคัดลอกไปยังเอกสารใหม่
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกเนื้อหาระหว่างย่อหน้าด้วยสไตล์เฉพาะโดยใช้วิธี ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
// Gather a list of the paragraphs using the respective heading styles. | |
List<Paragraph> parasStyleHeading1 = ParagraphsByStyleName(doc, "Heading 1"); | |
List<Paragraph> parasStyleHeading3 = ParagraphsByStyleName(doc, "Heading 3"); | |
// Use the first instance of the paragraphs with those styles. | |
Node startPara = parasStyleHeading1[0]; | |
Node endPara = parasStyleHeading3[0]; | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
List<Node> extractedNodes = ExtractContentHelper.ExtractContent(startPara, endPara, false); | |
Document dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodes); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenParagraphStyles.docx"); |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
public List<Paragraph> ParagraphsByStyleName(Document doc, string styleName) | |
{ | |
// Create an array to collect paragraphs of the specified style. | |
List<Paragraph> paragraphsWithStyle = new List<Paragraph>(); | |
NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true); | |
// Look through all paragraphs to find those with the specified style. | |
foreach (Paragraph paragraph in paragraphs) | |
{ | |
if (paragraph.ParagraphFormat.Style.Name == styleName) | |
paragraphsWithStyle.Add(paragraph); | |
} | |
return paragraphsWithStyle; | |
} |
แยกเนื้อหาระหว่างการรันเฉพาะ
คุณสามารถแยกเนื้อหาระหว่างโหนดอินไลน์ เช่น Run ได้เช่นกัน Runs จากย่อหน้าต่างๆ สามารถส่งผ่านเป็นเครื่องหมายได้ รหัสด้านล่างแสดงวิธีการแยกข้อความเฉพาะระหว่างโหนด Paragraph เดียวกัน
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกเนื้อหาระหว่างการรันเฉพาะของย่อหน้าเดียวกันโดยใช้วิธี ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
Paragraph para = (Paragraph) doc.GetChild(NodeType.Paragraph, 7, true); | |
Run startRun = para.Runs[1]; | |
Run endRun = para.Runs[4]; | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
List<Node> extractedNodes = ExtractContentHelper.ExtractContent(startRun, endRun, true); | |
foreach (Node extractedNode in extractedNodes) | |
Console.WriteLine(extractedNode.ToString(SaveFormat.Text)); |
แยกเนื้อหาโดยใช้ฟิลด์
หากต้องการใช้ช่องเป็นเครื่องหมาย ควรส่งโหนด FieldStart
พารามิเตอร์สุดท้ายของเมธอด ExtractContent
จะกำหนดว่าจะรวมฟิลด์ทั้งหมดหรือไม่ มาแยกเนื้อหาระหว่างช่องผสาน “FullName” และย่อหน้าในเอกสารกัน เราใช้วิธี MoveToMergeField ของคลาส DocumentBuilder สิ่งนี้จะส่งคืนโหนด FieldStart จากชื่อของฟิลด์ผสานที่ส่งผ่านไป
ในกรณีของเรา ให้ตั้งค่าพารามิเตอร์สุดท้ายที่ส่งไปยังวิธี ExtractContent เป็น false เพื่อแยกฟิลด์ออกจากการแยกข้อมูล เราจะแสดงเนื้อหาที่แยกออกมาเป็น PDF
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกเนื้อหาระหว่างเขตข้อมูลเฉพาะและย่อหน้าในเอกสารโดยใช้วิธี ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
// Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field. | |
// We could also get FieldStarts of a field using GetChildNode method as in the other examples. | |
builder.MoveToMergeField("Fullname", false, false); | |
// The builder cursor should be positioned at the start of the field. | |
FieldStart startField = (FieldStart) builder.CurrentNode; | |
Paragraph endPara = (Paragraph) doc.FirstSection.GetChild(NodeType.Paragraph, 5, true); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
List<Node> extractedNodes = ExtractContentHelper.ExtractContent(startField, endPara, false); | |
Document dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodes); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentUsingField.docx"); |
แยกเนื้อหาออกจากบุ๊กมาร์ก
ในเอกสาร เนื้อหาที่กำหนดไว้ภายในบุ๊กมาร์กจะถูกห่อหุ้มโดยโหนด BookmarkStart
และ BookmarkEnd เนื้อหาที่พบระหว่างสองโหนดนี้ประกอบขึ้นเป็นบุ๊กมาร์ก คุณสามารถส่งโหนดใดโหนดหนึ่งเหล่านี้เป็นเครื่องหมายใดก็ได้ แม้แต่โหนดจากบุ๊กมาร์กต่างๆ ก็ตาม ตราบใดที่เครื่องหมายเริ่มต้นปรากฏก่อนเครื่องหมายสิ้นสุดในเอกสาร เราจะแยกเนื้อหานี้ออกเป็นเอกสารใหม่โดยใช้โค้ดด้านล่าง ตัวเลือกพารามิเตอร์ IsInclusive แสดงวิธีเก็บรักษาหรือละทิ้งบุ๊กมาร์ก
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกเนื้อหาที่อ้างอิงถึงบุ๊กมาร์กโดยใช้วิธี ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
Bookmark bookmark = doc.Range.Bookmarks["Bookmark1"]; | |
BookmarkStart bookmarkStart = bookmark.BookmarkStart; | |
BookmarkEnd bookmarkEnd = bookmark.BookmarkEnd; | |
// Firstly, extract the content between these nodes, including the bookmark. | |
List<Node> extractedNodesInclusive = ExtractContentHelper.ExtractContent(bookmarkStart, bookmarkEnd, true); | |
Document dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodesInclusive); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx"); | |
// Secondly, extract the content between these nodes this time without including the bookmark. | |
List<Node> extractedNodesExclusive = ExtractContentHelper.ExtractContent(bookmarkStart, bookmarkEnd, false); | |
dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodesExclusive); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx"); |
แยกเนื้อหาออกจากความคิดเห็น
ความคิดเห็นประกอบด้วยโหนด CommentRangeStart, CommentRangeEnd และ Comment โหนดทั้งหมดเหล่านี้เป็นแบบอินไลน์ สองโหนดแรกสรุปเนื้อหาในเอกสารซึ่งมีการอ้างอิงโดยความคิดเห็น ดังที่เห็นในภาพหน้าจอด้านล่าง
โหนด Comment นั้นเป็น InlineStory ที่สามารถประกอบด้วยย่อหน้าและเรียกใช้ได้ โดยจะแสดงข้อความของความคิดเห็นตามที่เห็นเป็นกรอบความคิดเห็นในบานหน้าต่างบทวิจารณ์ เนื่องจากโหนดนี้เป็นแบบอินไลน์และสืบทอดจากเนื้อหา คุณจึงสามารถแยกเนื้อหาจากภายในข้อความนี้ได้เช่นกัน
ความคิดเห็นจะสรุปส่วนหัว ย่อหน้าแรก และตารางในส่วนที่สอง มาแยกความคิดเห็นนี้ออกเป็นเอกสารใหม่ ตัวเลือก IsInclusive กำหนดว่าความคิดเห็นนั้นจะถูกเก็บไว้หรือละทิ้ง
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการทำเช่นนี้:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
CommentRangeStart commentStart = (CommentRangeStart) doc.GetChild(NodeType.CommentRangeStart, 0, true); | |
CommentRangeEnd commentEnd = (CommentRangeEnd) doc.GetChild(NodeType.CommentRangeEnd, 0, true); | |
// Firstly, extract the content between these nodes including the comment as well. | |
List<Node> extractedNodesInclusive = ExtractContentHelper.ExtractContent(commentStart, commentEnd, true); | |
Document dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodesInclusive); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx"); | |
// Secondly, extract the content between these nodes without the comment. | |
List<Node> extractedNodesExclusive = ExtractContentHelper.ExtractContent(commentStart, commentEnd, false); | |
dstDoc = ExtractContentHelper.GenerateDocument(doc, extractedNodesExclusive); | |
dstDoc.Save(ArtifactsDir + "ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx"); |
วิธีแยกเนื้อหาโดยใช้ DocumentVisitor
ใช้คลาส DocumentVisitor เพื่อใช้สถานการณ์การใช้งานนี้ คลาสนี้สอดคล้องกับรูปแบบการออกแบบผู้เยี่ยมชมที่รู้จักกันดี ด้วย DocumentVisitor , คุณสามารถกำหนดและดำเนินการแบบกำหนดเองที่จำเป็นต้องมีการแจงนับบนแผนผังเอกสารได้
DocumentVisitor จัดเตรียมชุดวิธีการ VisitXXX ที่จะเรียกใช้เมื่อพบองค์ประกอบเอกสาร (โหนด) โดยเฉพาะ ตัวอย่างเช่น VisitParagraphStart จะถูกเรียกเมื่อพบจุดเริ่มต้นของย่อหน้าข้อความ และ VisitParagraphEnd จะถูกเรียกเมื่อพบจุดสิ้นสุดของย่อหน้าข้อความ แต่ละวิธีของ DocumentVisitor.VisitXXX จะยอมรับออบเจ็กต์ที่เกี่ยวข้องซึ่งพบเพื่อให้คุณสามารถใช้งานได้ตามต้องการ (เช่น ดึงการจัดรูปแบบ) เช่น ทั้ง DocumentVisitor.VisitParagraphStart และ DocumentVisitor.VisitParagraphEnd ยอมรับออบเจ็กต์ Paragraph
วิธีการ DocumentVisitor.VisitXXX แต่ละรายการจะส่งกลับค่า VisitorAction ที่ควบคุมการแจงนับโหนด คุณสามารถร้องขอให้ทำการแจงนับต่อไป ข้ามโหนดปัจจุบัน (แต่ทำการแจงนับต่อไป) หรือหยุดการแจงนับของโหนด
ต่อไปนี้เป็นขั้นตอนที่คุณควรปฏิบัติตามเพื่อกำหนดและแยกส่วนต่างๆ ของเอกสารโดยทางโปรแกรม:
- สร้างคลาสที่ได้รับมาจาก DocumentVisitor
- แทนที่และจัดเตรียมการใช้งานสำหรับวิธี DocumentVisitor.VisitXXX บางส่วนหรือทั้งหมดเพื่อดำเนินการแบบกำหนดเองบางอย่าง
- เรียก Node.Accept บนโหนดที่คุณต้องการเริ่มการแจงนับ เช่น หากคุณต้องการแจงนับเอกสารทั้งหมด ให้ใช้ Document.Accept
DocumentVisitor จัดเตรียมการใช้งานเริ่มต้นสำหรับวิธี DocumentVisitor.VisitXXX ทั้งหมด ซึ่งช่วยให้สร้างผู้เยี่ยมชมเอกสารใหม่ได้ง่ายขึ้น เนื่องจากเฉพาะวิธีการที่จำเป็นสำหรับผู้เยี่ยมชมรายใดรายหนึ่งเท่านั้นที่จำเป็นต้องถูกแทนที่ ไม่จำเป็นต้องแทนที่วิธีการของผู้เข้าชมทั้งหมด
ตัวอย่างต่อไปนี้แสดงวิธีใช้รูปแบบผู้เยี่ยมชมเพื่อเพิ่มการดำเนินการใหม่ให้กับโมเดลออบเจ็กต์ Aspose.Words ในกรณีนี้ เราสร้างตัวแปลงเอกสารอย่างง่ายเป็นรูปแบบข้อความ:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Extract content.docx"); | |
ConvertDocToTxt convertToPlainText = new ConvertDocToTxt(); | |
// Note that every node in the object model has the accept method so the visiting | |
// can be executed not only for the whole document, but for any node in the document. | |
doc.Accept(convertToPlainText); | |
// Once the visiting is complete, we can retrieve the result of the operation, | |
// That in this example, has accumulated in the visitor. | |
Console.WriteLine(convertToPlainText.GetText()); |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
/// <summary> | |
/// Simple implementation of saving a document in the plain text format. Implemented as a Visitor. | |
/// </summary> | |
internal class ConvertDocToTxt : DocumentVisitor | |
{ | |
public ConvertDocToTxt() | |
{ | |
mIsSkipText = false; | |
mBuilder = new StringBuilder(); | |
} | |
/// <summary> | |
/// Gets the plain text of the document that was accumulated by the visitor. | |
/// </summary> | |
public string GetText() | |
{ | |
return mBuilder.ToString(); | |
} | |
/// <summary> | |
/// Called when a Run node is encountered in the document. | |
/// </summary> | |
public override VisitorAction VisitRun(Run run) | |
{ | |
AppendText(run.Text); | |
// Let the visitor continue visiting other nodes. | |
return VisitorAction.Continue; | |
} | |
/// <summary> | |
/// Called when a FieldStart node is encountered in the document. | |
/// </summary> | |
public override VisitorAction VisitFieldStart(FieldStart fieldStart) | |
{ | |
// In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows | |
// after a field start character. We want to skip field codes and output field. | |
// Result only, therefore we use a flag to suspend the output while inside a field code. | |
// Note this is a very simplistic implementation and will not work very well. | |
// If you have nested fields in a document. | |
mIsSkipText = true; | |
return VisitorAction.Continue; | |
} | |
/// <summary> | |
/// Called when a FieldSeparator node is encountered in the document. | |
/// </summary> | |
public override VisitorAction VisitFieldSeparator(FieldSeparator fieldSeparator) | |
{ | |
// Once reached a field separator node, we enable the output because we are | |
// now entering the field result nodes. | |
mIsSkipText = false; | |
return VisitorAction.Continue; | |
} | |
/// <summary> | |
/// Called when a FieldEnd node is encountered in the document. | |
/// </summary> | |
public override VisitorAction VisitFieldEnd(FieldEnd fieldEnd) | |
{ | |
// Make sure we enable the output when reached a field end because some fields | |
// do not have field separator and do not have field result. | |
mIsSkipText = false; | |
return VisitorAction.Continue; | |
} | |
/// <summary> | |
/// Called when visiting of a Paragraph node is ended in the document. | |
/// </summary> | |
public override VisitorAction VisitParagraphEnd(Paragraph paragraph) | |
{ | |
// When outputting to plain text we output Cr+Lf characters. | |
AppendText(ControlChar.CrLf); | |
return VisitorAction.Continue; | |
} | |
public override VisitorAction VisitBodyStart(Body body) | |
{ | |
// We can detect beginning and end of all composite nodes such as Section, Body, | |
// Table, Paragraph etc and provide custom handling for them. | |
mBuilder.Append("*** Body Started ***\r\n"); | |
return VisitorAction.Continue; | |
} | |
public override VisitorAction VisitBodyEnd(Body body) | |
{ | |
mBuilder.Append("*** Body Ended ***\r\n"); | |
return VisitorAction.Continue; | |
} | |
/// <summary> | |
/// Called when a HeaderFooter node is encountered in the document. | |
/// </summary> | |
public override VisitorAction VisitHeaderFooterStart(HeaderFooter headerFooter) | |
{ | |
// Returning this value from a visitor method causes visiting of this | |
// Node to stop and move on to visiting the next sibling node | |
// The net effect in this example is that the text of headers and footers | |
// Is not included in the resulting output | |
return VisitorAction.SkipThisNode; | |
} | |
/// <summary> | |
/// Adds text to the current output. Honors the enabled/disabled output flag. | |
/// </summary> | |
private void AppendText(string text) | |
{ | |
if (!mIsSkipText) | |
mBuilder.Append(text); | |
} | |
private readonly StringBuilder mBuilder; | |
private bool mIsSkipText; | |
} |
วิธีการแยกข้อความเท่านั้น
วิธีดึงข้อความจากเอกสารคือ:
- ใช้ Document.Save กับ SaveFormat.Text เพื่อบันทึกเป็นข้อความธรรมดาลงในไฟล์หรือสตรีม
- ใช้ Node.ToString และส่งพารามิเตอร์ SaveFormat.Text ภายใน สิ่งนี้จะเรียกใช้การบันทึกเป็นข้อความลงในสตรีมหน่วยความจำและส่งกลับสตริงผลลัพธ์
- ใช้ Node.GetText เพื่อดึงข้อความที่มีอักขระควบคุม Microsoft Word ทั้งหมดรวมถึงโค้ดฟิลด์
- ใช้ DocumentVisitor แบบกำหนดเองเพื่อดำเนินการแยกแบบกำหนดเอง
การใช้ Node.GetText
และ Node.ToString
เอกสาร Word สามารถประกอบด้วยอักขระควบคุมที่กำหนดองค์ประกอบพิเศษ เช่น ฟิลด์ ส่วนท้ายของเซลล์ ส่วนท้ายของส่วน เป็นต้น รายการอักขระควบคุม Word ที่เป็นไปได้ทั้งหมดถูกกำหนดไว้ในคลาส ControlChar วิธีการ Node.GetText ส่งคืนข้อความที่มีอักขระควบคุมทั้งหมดอยู่ในโหนด
การเรียก ToString จะส่งกลับการแสดงข้อความธรรมดาของเอกสารโดยไม่มีอักขระควบคุมเท่านั้น สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการส่งออกเป็นข้อความธรรมดา โปรดดูที่ส่วน “การใช้ SaveFormat.Text” ต่อไปนี้
ตัวอย่างโค้ดต่อไปนี้แสดงความแตกต่างระหว่างการเรียกเมธอด GetText และ ToString บนโหนด:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(); | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
builder.InsertField("MERGEFIELD Field"); | |
// When converted to text it will not retrieve fields code or special characters, | |
// but will still contain some natural formatting characters such as paragraph markers etc. | |
// This is the same as "viewing" the document as if it was opened in a text editor. | |
Console.WriteLine("Convert to text result: " + doc.ToString(SaveFormat.Text)); |
การใช้ SaveFormat.Text
ตัวอย่างนี้จะบันทึกเอกสารดังต่อไปนี้:
- กรองอักขระฟิลด์และรหัสฟิลด์ รูปร่าง เชิงอรรถ อ้างอิงท้ายเรื่อง และการอ้างอิงความคิดเห็น
- แทนที่อักขระ ControlChar.Cr ที่ส่วนท้ายของย่อหน้าด้วยชุดค่าผสม ControlChar.CrLf
- ใช้การเข้ารหัส UTF8
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการบันทึกเอกสารในรูปแบบ TXT:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Document.docx"); | |
doc.Save(ArtifactsDir + "BaseConversions.DocxToTxt.txt"); |
แยกรูปภาพออกจากรูปร่าง
คุณอาจต้องแยกรูปภาพเอกสารเพื่อทำงานบางอย่าง Aspose.Words ให้คุณทำเช่นนี้ได้เช่นกัน
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการแยกรูปภาพจากเอกสาร:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git. | |
Document doc = new Document(MyDir + "Images.docx"); | |
NodeCollection shapes = doc.GetChildNodes(NodeType.Shape, true); | |
int imageIndex = 0; | |
foreach (Shape shape in shapes) | |
{ | |
if (shape.HasImage) | |
{ | |
string imageFileName = | |
$"Image.ExportImages.{imageIndex}_{FileFormatUtil.ImageTypeToExtension(shape.ImageData.ImageType)}"; | |
// Note, if you have only an image (not a shape with a text and the image), | |
// you can use shape.GetShapeRenderer().Save(...) method to save the image. | |
shape.ImageData.Save(ArtifactsDir + imageFileName); | |
imageIndex++; | |
} | |
} |