استخراج المحتوى بين العقد في مستند
عند العمل مع المستندات، من المهم أن تكون قادرا على استخراج المحتوى بسهولة من نطاق معين داخل المستند. ومع ذلك، قد يتكون المحتوى من عناصر معقدة مثل الفقرات والجداول والصور وما إلى ذلك.
بغض النظر عن المحتوى الذي يجب استخراجه، سيتم دائما تحديد طريقة استخراج هذا المحتوى من خلال العقد التي يتم اختيارها لاستخراج المحتوى بينها. يمكن أن تكون هذه هيئات نصية كاملة أو عمليات تشغيل نصية بسيطة.
هناك العديد من المواقف المحتملة وبالتالي العديد من أنواع العقدة المختلفة التي يجب مراعاتها عند استخراج المحتوى. على سبيل المثال، قد ترغب في استخراج المحتوى بين:
- فقرتان محددتان
- أشواط محددة من النص
- حقول من أنواع مختلفة، مثل حقول الدمج
- بداية ونهاية نطاقات إشارة مرجعية أو تعليق
- الهيئات المختلفة للنصوص الواردة في أقسام منفصلة
في بعض الحالات، قد تحتاج حتى إلى الجمع بين أنواع عقدة مختلفة، مثل استخراج المحتوى بين فقرة وحقل، أو بين تشغيل وإشارة مرجعية.
توفر هذه المقالة تنفيذ التعليمات البرمجية لاستخراج النص بين العقد المختلفة، بالإضافة إلى أمثلة للسيناريوهات الشائعة.
لماذا استخراج المحتوى
غالبا ما يكون الهدف من استخراج المحتوى هو تكراره أو حفظه بشكل منفصل في مستند جديد. على سبيل المثال، يمكنك استخراج المحتوى و:
- انسخه في مستند منفصل
- تحويل جزء معين من المستند إلى PDF أو صورة
- تكرار المحتوى في المستند عدة مرات
- العمل مع المحتوى المستخرج بشكل منفصل عن بقية المستند
يمكن تحقيق ذلك بسهولة باستخدام Aspose.Words وتنفيذ التعليمات البرمجية أدناه.
استخراج خوارزمية المحتوى
يتناول الرمز في هذا القسم جميع المواقف المحتملة الموضحة أعلاه بطريقة واحدة معممة وقابلة لإعادة الاستخدام. يتضمن المخطط العام لهذه التقنية:
- جمع العقد التي تملي مجال المحتوى الذي سيتم استخراجه من المستند. يتم التعامل مع استرداد هذه العقد من قبل المستخدم في التعليمات البرمجية الخاصة بهم، بناء على ما يريدون استخراجه.
- تمرير هذه العقد إلى طريقة ExtractContent الواردة أدناه. يجب عليك أيضا تمرير معلمة منطقية تنص على ما إذا كان يجب تضمين هذه العقد، التي تعمل كعلامات، في الاستخراج أم لا.
- استرجاع قائمة المحتوى المستنسخ (العقد المنسوخة) المحددة ليتم استخراجها. يمكنك استخدام قائمة العقد هذه بأي طريقة قابلة للتطبيق، على سبيل المثال، إنشاء مستند جديد يحتوي على المحتوى المحدد فقط.
كيفية استخراج المحتوى
لاستخراج المحتوى من المستند الخاص بك، تحتاج إلى استدعاء طريقة ExtractContent
أدناه وتمرير المعلمات المناسبة. يتضمن الأساس الأساسي لهذه الطريقة العثور على عقد على مستوى الكتلة (فقرات وجداول) واستنساخها لإنشاء نسخ متطابقة. إذا كانت عقد العلامة التي تم تمريرها على مستوى الكتلة، فإن الطريقة قادرة ببساطة على نسخ المحتوى على هذا المستوى وإضافته إلى المصفوفة.
ومع ذلك، إذا كانت العقد علامة مضمنة (طفل من فقرة) ثم يصبح الوضع أكثر تعقيدا، كما أنه من الضروري تقسيم الفقرة في عقدة مضمنة، سواء كان ذلك تشغيل، حقول المرجعية الخ. تتم إزالة المحتوى الموجود في العقد الأصلية المستنسخة غير الموجودة بين العلامات. يتم استخدام هذه العملية للتأكد من أن العقد المضمنة ستظل تحتفظ بتنسيق الفقرة الأصل. ستعمل الطريقة أيضا على إجراء فحوصات على العقد التي تم تمريرها كمعلمات وتلقي استثناء إذا كانت أي عقدة غير صالحة. المعلمات التي سيتم تمريرها إلى هذه الطريقة هي:
-
StartNode و EndNode. المعلمات الأولين هي العقد التي تحدد حيث استخراج المحتوى هو أن تبدأ وتنتهي في على التوالي. يمكن أن تكون هذه العقد على مستوى الكتلة (فقرة، جدول ) أو على مستوى مضمن (على سبيل المثال تشغيل، FieldStart، BookmarkStart إلخ.):
- لتمرير حقل، يجب عليك تمرير الكائن FieldStart المقابل.
- لتمرير الإشارات المرجعية، يجب تمرير العقدتين BookmarkStart و BookmarkEnd.
- لتمرير التعليقات، يجب استخدام العقدتين CommentRangeStart و CommentRangeEnd.
-
IsInclusive. يحدد ما إذا كانت العلامات مدرجة في الاستخراج أم لا. إذا تم تعيين هذا الخيار على خطأ وتم تمرير نفس العقدة أو العقد المتتالية، فسيتم إرجاع قائمة فارغة:
- إذا تم تمرير عقدة FieldStart، فإن هذا الخيار يحدد ما إذا كان سيتم تضمين الحقل بأكمله أو استبعاده.
- إذا تم تمرير عقدة BookmarkStart أو BookmarkEnd، فإن هذا الخيار يحدد ما إذا كانت الإشارة المرجعية مضمنة أو المحتوى فقط بين نطاق الإشارة المرجعية.
- إذا تم تمرير عقدة CommentRangeStart أو CommentRangeEnd، فإن هذا الخيار يحدد ما إذا كان سيتم تضمين التعليق نفسه أو المحتوى فقط في نطاق التعليقات.
تنفيذ طريقة ExtractContent يمكنك أن تجد هنا. ستتم الإشارة إلى هذه الطريقة في السيناريوهات الواردة في هذه المقالة.
سنحدد أيضا طريقة مخصصة لإنشاء مستند بسهولة من العقد المستخرجة. تستخدم هذه الطريقة في العديد من السيناريوهات أدناه وتقوم ببساطة بإنشاء مستند جديد واستيراد المحتوى المستخرج إليه.
يوضح مثال الكود التالي كيفية أخذ قائمة بالعقد وإدراجها في مستند جديد.
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
static SharedPtr<Document> GenerateDocument(SharedPtr<Document> srcDoc, SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> nodes) | |
{ | |
auto dstDoc = MakeObject<Document>(); | |
// Remove the first paragraph from the empty document. | |
dstDoc->get_FirstSection()->get_Body()->RemoveAllChildren(); | |
// Import each node from the list into the new document. Keep the original formatting of the node. | |
auto importer = MakeObject<NodeImporter>(srcDoc, dstDoc, ImportFormatMode::KeepSourceFormatting); | |
for (const auto& node : nodes) | |
{ | |
SharedPtr<Node> importNode = importer->ImportNode(node, true); | |
dstDoc->get_FirstSection()->get_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-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto startPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->get_Body()->GetChild(NodeType::Paragraph, 6, true)); | |
auto endPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->get_Body()->GetChild(NodeType::Paragraph, 10, true)); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara, endPara, true); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenParagraphs.docx"); |
استخراج المحتوى بين أنواع مختلفة من العقد
يمكننا استخراج المحتوى بين أي مجموعات من العقد على مستوى الكتلة أو العقد المضمنة. في هذا السيناريو أدناه، سنستخرج المحتوى بين الفقرة الأولى والجدول في القسم الثاني بشكل شامل. نحصل على عقد العلامات عن طريق استدعاء طريقة Body.FirstParagraph
و GetChild في القسم الثاني من المستند لاسترداد الفقرة المناسبة وعقد الجدول. للحصول على اختلاف طفيف، دعنا نكرر المحتوى بدلا من ذلك وأدخله أسفل النص الأصلي.
يوضح مثال الكود التالي كيفية استخراج المحتوى بين فقرة وجدول باستخدام طريقة ExtractContent
:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto startPara = System::ExplicitCast<Paragraph>(doc->get_LastSection()->GetChild(NodeType::Paragraph, 2, true)); | |
auto endTable = System::ExplicitCast<Table>(doc->get_LastSection()->GetChild(NodeType::Table, 0, true)); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara, endTable, true); | |
// Let's reverse the array to make inserting the content back into the document easier. | |
extractedNodes->Reverse(); | |
for (SharedPtr<Node> extractedNode : extractedNodes) | |
// Insert the last node from the reversed list. | |
endTable->get_ParentNode()->InsertAfter(extractedNode, endTable); | |
doc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBlockLevelNodes.docx"); |
استخراج المحتوى بين الفقرات على أساس النمط
قد تحتاج إلى استخراج المحتوى بين فقرات من نفس الأنماط أو أنماط مختلفة، مثل بين الفقرات المميزة بأنماط العناوين. يوضح الرمز أدناه كيفية تحقيق ذلك. إنه مثال بسيط سيستخرج المحتوى بين المثيل الأول لأنماط" العنوان 1 “و” الرأس 3 " دون استخراج العناوين أيضا. للقيام بذلك، قمنا بتعيين المعلمة الأخيرة على خطأ، والتي تحدد أنه لا ينبغي تضمين عقد العلامة.
في التنفيذ السليم، يجب تشغيل هذا في حلقة لاستخراج المحتوى بين جميع فقرات هذه الأنماط من المستند. يتم نسخ المحتوى المستخرج في مستند جديد.
يوضح مثال الكود التالي كيفية استخراج المحتوى بين الفقرات بأنماط محددة باستخدام طريقة ExtractContent
:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
// Gather a list of the paragraphs using the respective heading styles. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> parasStyleHeading1 = ParagraphsByStyleName(doc, u"Heading 1"); | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> parasStyleHeading3 = ParagraphsByStyleName(doc, u"Heading 3"); | |
// Use the first instance of the paragraphs with those styles. | |
SharedPtr<Node> startPara1 = parasStyleHeading1->idx_get(0); | |
SharedPtr<Node> endPara1 = parasStyleHeading3->idx_get(0); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara1, endPara1, false); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenParagraphStyles.docx"); |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
static SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> ParagraphsByStyleName(SharedPtr<Document> doc, System::String styleName) | |
{ | |
// Create an array to collect paragraphs of the specified style. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> paragraphsWithStyle = | |
MakeObject<System::Collections::Generic::List<SharedPtr<Paragraph>>>(); | |
SharedPtr<NodeCollection> paragraphs = doc->GetChildNodes(NodeType::Paragraph, true); | |
// Look through all paragraphs to find those with the specified style. | |
for (const auto& paragraph : System::IterateOver<Paragraph>(paragraphs)) | |
{ | |
if (paragraph->get_ParagraphFormat()->get_Style()->get_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-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto para = System::ExplicitCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 7, true)); | |
SharedPtr<Run> startRun = para->get_Runs()->idx_get(1); | |
SharedPtr<Run> endRun = para->get_Runs()->idx_get(4); | |
// Extract the content between these nodes in the document. Include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startRun, endRun, true); | |
for (SharedPtr<Node> extractedNode : extractedNodes) | |
std::cout << extractedNode->ToString(SaveFormat::Text) << std::endl; |
استخراج المحتوى باستخدام حقل
لاستخدام حقل كعلامة، يجب تمرير العقدة FieldStart
. ستحدد المعلمة الأخيرة لطريقة ExtractContent
ما إذا كان سيتم تضمين الحقل بأكمله أم لا. دعنا نستخرج المحتوى بين حقل الدمج “FullName " وفقرة في المستند. نستخدم طريقة MoveToMergeField لفئة DocumentBuilder. سيؤدي هذا إلى إرجاع العقدة FieldStart من اسم حقل الدمج الذي تم تمريره إليه.
في حالتنا، دعنا نضبط المعلمة الأخيرة التي تم تمريرها إلى طريقة ExtractContent إلى خطأ لاستبعاد الحقل من الاستخراج. سنقدم المحتوى المستخرج إلى PDF.
يوضح مثال الكود التالي كيفية استخراج المحتوى بين حقل معين وفقرة في المستند باستخدام طريقة ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto builder = MakeObject<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(u"Fullname", false, false); | |
// The builder cursor should be positioned at the start of the field. | |
auto startField = System::ExplicitCast<FieldStart>(builder->get_CurrentNode()); | |
auto endPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->GetChild(NodeType::Paragraph, 5, true)); | |
// Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startField, endPara, false); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentUsingField.docx"); |
استخراج المحتوى من إشارة مرجعية
في المستند، يتم تغليف المحتوى المحدد داخل إشارة مرجعية بواسطة العقدتين BookmarkStart
و BookmarkEnd. يشكل المحتوى الموجود بين هاتين العقدتين الإشارة المرجعية. يمكنك تمرير أي من هذه العقد كأي علامة، حتى تلك من إشارات مرجعية مختلفة، طالما تظهر علامة البداية قبل علامة النهاية في المستند. سنقوم باستخراج هذا المحتوى في مستند جديد باستخدام الرمز أدناه. يوضح خيار المعلمة IsInclusive كيفية الاحتفاظ بالإشارة المرجعية أو تجاهلها.
يوضح مثال التعليمات البرمجية التالية كيفية استخراج المحتوى المشار إليه إشارة مرجعية باستخدام طريقة ExtractContent:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
SharedPtr<Bookmark> bookmark = doc->get_Range()->get_Bookmarks()->idx_get(u"Bookmark1"); | |
SharedPtr<BookmarkStart> bookmarkStart = bookmark->get_BookmarkStart(); | |
SharedPtr<BookmarkEnd> bookmarkEnd = bookmark->get_BookmarkEnd(); | |
// Firstly, extract the content between these nodes, including the bookmark. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesInclusive = | |
ExtractContentHelper::ExtractContent(bookmarkStart, bookmarkEnd, true); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesInclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx"); | |
// Secondly, extract the content between these nodes this time without including the bookmark. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesExclusive = | |
ExtractContentHelper::ExtractContent(bookmarkStart, bookmarkEnd, false); | |
dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesExclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx"); |
استخراج المحتوى من تعليق
يتكون التعليق من CommentRangeStart، CommentRangeEnd وعقد التعليق. كل هذه العقد مضمنة. تقوم العقدتان الأوليان بتغليف المحتوى في المستند المشار إليه بواسطة التعليق، كما هو موضح في لقطة الشاشة أدناه.
العقدة Comment نفسها هي InlineStory التي يمكن أن تحتوي على فقرات وتشغيل. يمثل رسالة التعليق كما ينظر إليه على أنه فقاعة تعليق في جزء المعاينة. نظرا لأن هذه العقدة مضمنة وسليل الجسم، يمكنك أيضا استخراج المحتوى من داخل هذه الرسالة أيضا.
يلخص التعليق العنوان والفقرة الأولى والجدول في القسم الثاني. دعنا نستخرج هذا التعليق في مستند جديد. يحدد الخيار IsInclusive إذا تم الاحتفاظ بالتعليق نفسه أو تجاهله.
يوضح مثال الكود التالي كيفية القيام بذلك:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto commentStart = System::ExplicitCast<CommentRangeStart>(doc->GetChild(NodeType::CommentRangeStart, 0, true)); | |
auto commentEnd = System::ExplicitCast<CommentRangeEnd>(doc->GetChild(NodeType::CommentRangeEnd, 0, true)); | |
// Firstly, extract the content between these nodes including the comment as well. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesInclusive = | |
ExtractContentHelper::ExtractContent(commentStart, commentEnd, true); | |
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesInclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx"); | |
// Secondly, extract the content between these nodes without the comment. | |
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesExclusive = | |
ExtractContentHelper::ExtractContent(commentStart, commentEnd, false); | |
dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesExclusive); | |
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx"); |
كيفية استخراج المحتوى باستخدام DocumentVisitor
استخدم فئة DocumentVisitor لتنفيذ سيناريو الاستخدام هذا. يتوافق هذا الفصل مع نمط تصميم الزائر المعروف. باستخدام DocumentVisitor,، يمكنك تحديد وتنفيذ العمليات المخصصة التي تتطلب التعداد عبر شجرة المستندات.
DocumentVisitor
ترجع كل طريقة DocumentVisitor.VisitXXX قيمة VisitorAction تتحكم في تعداد العقد. يمكنك طلب إما متابعة التعداد، أو تخطي العقدة الحالية (ولكن متابعة التعداد)، أو إيقاف تعداد العقد.
هذه هي الخطوات التي يجب عليك اتباعها لتحديد واستخراج أجزاء مختلفة من المستند برمجيا:
- إنشاء فئة مشتقة من DocumentVisitor
- تجاوز وتوفير تطبيقات لبعض أو كل طرق DocumentVisitor.VisitXXX لتنفيذ بعض العمليات المخصصة
- استدعاء
Node.Accept
على العقدة من حيث تريد بدء التعداد. على سبيل المثال، إذا كنت تريد تعداد المستند بأكمله، فاستخدمDocument.Accept
DocumentVisitor
يوضح هذا المثال كيفية استخدام نمط الزائر لإضافة عمليات جديدة إلى نموذج الكائن Aspose.Words. في هذه الحالة، نقوم بإنشاء محول مستند بسيط إلى تنسيق نصي:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx"); | |
auto convertToPlainText = MakeObject<ExtractContent::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. | |
std::cout << convertToPlainText->GetText() << std::endl; |
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
/// <summary> | |
/// Simple implementation of saving a document in the plain text format. Implemented as a Visitor. | |
/// </summary> | |
class ConvertDocToTxt : public DocumentVisitor | |
{ | |
public: | |
ConvertDocToTxt() : mIsSkipText(false) | |
{ | |
mIsSkipText = false; | |
mBuilder = MakeObject<System::Text::StringBuilder>(); | |
} | |
/// <summary> | |
/// Gets the plain text of the document that was accumulated by the visitor. | |
/// </summary> | |
String GetText() | |
{ | |
return mBuilder->ToString(); | |
} | |
/// <summary> | |
/// Called when a Run node is encountered in the document. | |
/// </summary> | |
VisitorAction VisitRun(SharedPtr<Run> run) override | |
{ | |
AppendText(run->get_Text()); | |
// Let the visitor continue visiting other nodes. | |
return VisitorAction::Continue; | |
} | |
/// <summary> | |
/// Called when a FieldStart node is encountered in the document. | |
/// </summary> | |
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override | |
{ | |
ASPOSE_UNUSED(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> | |
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override | |
{ | |
ASPOSE_UNUSED(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> | |
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override | |
{ | |
ASPOSE_UNUSED(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> | |
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override | |
{ | |
ASPOSE_UNUSED(paragraph); | |
// When outputting to plain text we output Cr+Lf characters. | |
AppendText(ControlChar::CrLf()); | |
return VisitorAction::Continue; | |
} | |
VisitorAction VisitBodyStart(SharedPtr<Body> body) override | |
{ | |
ASPOSE_UNUSED(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(u"*** Body Started ***\r\n"); | |
return VisitorAction::Continue; | |
} | |
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override | |
{ | |
ASPOSE_UNUSED(body); | |
mBuilder->Append(u"*** Body Ended ***\r\n"); | |
return VisitorAction::Continue; | |
} | |
/// <summary> | |
/// Called when a HeaderFooter node is encountered in the document. | |
/// </summary> | |
VisitorAction VisitHeaderFooterStart(SharedPtr<HeaderFooter> headerFooter) override | |
{ | |
ASPOSE_UNUSED(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; | |
} | |
private: | |
SharedPtr<System::Text::StringBuilder> mBuilder; | |
bool mIsSkipText; | |
/// <summary> | |
/// Adds text to the current output. Honors the enabled/disabled output flag. | |
/// </summary> | |
void AppendText(String text) | |
{ | |
if (!mIsSkipText) | |
{ | |
mBuilder->Append(text); | |
} | |
} | |
}; |
كيفية استخراج النص فقط
طرق استرداد النص من المستند هي:
- استخدم Document.Save مع SaveFormat.Text للحفظ كنص عادي في ملف أو دفق
- استخدم Node.ToString وتمرير المعلمة SaveFormat.Text. داخليا، يستدعي هذا حفظ كنص في دفق ذاكرة وإرجاع السلسلة الناتجة
- استخدم Node.GetText لاسترداد النص مع جميع أحرف التحكم Microsoft Word بما في ذلك رموز الحقول
- تنفيذ مخصص DocumentVisitor لإجراء استخراج مخصص
باستخدام Node.GetText
و Node.ToString
يمكن أن يحتوي مستند الكلمة على أحرف تحكم تحدد عناصر خاصة مثل الحقل ونهاية الخلية ونهاية القسم وما إلى ذلك. يتم تعريف القائمة الكاملة لأحرف التحكم في الكلمات المحتملة في فئة ControlChar. تقوم طريقة Node.GetText بإرجاع النص مع جميع أحرف حرف التحكم الموجودة في العقدة.
يؤدي الاتصال ToString إلى إرجاع تمثيل النص العادي للمستند فقط بدون أحرف تحكم.
يوضح مثال الكود التالي الفرق بين استدعاء طرق GetText و ToString على عقدة:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(); | |
auto builder = MakeObject<DocumentBuilder>(doc); | |
builder->InsertField(u"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. | |
std::cout << (String(u"ToString() Result: ") + doc->ToString(SaveFormat::Text)) << std::endl; |
باستخدام 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-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Document.docx"); | |
doc->Save(ArtifactsDir + u"BaseConversions.DocxToTxt.txt"); |
استخراج الصور من الأشكال
قد تحتاج إلى استخراج صور المستندات لأداء بعض المهام. Aspose.Words يسمح لك أن تفعل هذا أيضا.
يوضح مثال الكود التالي كيفية استخراج الصور من مستند:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git. | |
auto doc = MakeObject<Document>(MyDir + u"Images.docx"); | |
SharedPtr<NodeCollection> shapes = doc->GetChildNodes(NodeType::Shape, true); | |
int imageIndex = 0; | |
for (const auto& shape : System::IterateOver<Shape>(shapes)) | |
{ | |
if (shape->get_HasImage()) | |
{ | |
String imageFileName = | |
String::Format(u"Image.ExportImages.{0}_{1}", imageIndex, FileFormatUtil::ImageTypeToExtension(shape->get_ImageData()->get_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->get_ImageData()->Save(ArtifactsDir + imageFileName); | |
imageIndex++; | |
} | |
} |