الرئيسية
» WINDOWS
»
قسّم ملفات XML الكبيرة بسرعة باستخدام برنامج بايثون آمن
قسّم ملفات XML الكبيرة بسرعة باستخدام برنامج بايثون آمن
لتقسيم ملف XML كبير بسرعة، قسّمه عند السجلات المتكررة الكاملة بدلاً من اقتطاع أجزاء منه. يستخدم المثال أدناه مكتبة بايثون القياسية لمعالجة المدخلات وكتابة مستندات XML منفصلة بنفس العنصر الجذر وسماته. وهو مصمم لبنية شائعة مثل <script> <records><record>...</record><record>...</record></records>، حيث يمثل كل عنصر فرعي مباشر للعنصر الجذر سجلاً مستقلاً.
قم بالتقسيم عند سجلات الأبناء المباشرين المتكررة تحت الجذر؛ يمكن أن تؤدي حدود البايت العشوائية إلى كسر ترميز XML.
اختر نقطة تقسيم آمنة
يحتوي مستند XML على عنصر مستند واحد، ويجب أن تتداخل وسومه بشكل صحيح. يمكن لأداة تقسيم الملفات الخام أن تقطع وسم البداية، أو سجلًا متداخلًا، أو حتى تسلسل ترميز الأحرف، تاركةً أجزاءً لا تُمثل XML مستقلة. توضح مواصفات W3C XML قواعد المستند السليم وعناصر الجذر.
قبل تقسيم الملف، افحصه وحدد عنصر السجل المكرر. يتعامل هذا البرنامج النصي مع كل عنصر فرعي مباشر تحت الجذر كوحدة واحدة. استخدمه فقط عندما تكون هذه العناصر الفرعية سجلات مستقلة، ولا يحتوي الجذر نفسه على أي نص مختلط ذي معنى أو بيانات وصفية يجب أن تظهر في مكان معين. إذا كانت السجلات متداخلة على عدة مستويات، فاستخدم أداة تقسيم مصممة خصيصًا لمفردات XML هذه بدلًا من تعديل البرنامج النصي بشكل عشوائي.
ماذا عن أداة تقسيم XML / OOXP؟
أشارت المقالة الأصلية إلى برنامج Split That XML. لا تزال صفحة المشروع على موقع SourceForge تصف البرنامج، لكنها تُشير إلى أن آخر تحديث له كان في 27 سبتمبر 2015. تعامل معه كبرنامج قديم: فادعاء التوافق مع نظام Windows القديم لا يُؤكد دعمه للأنظمة الحالية. إذا كان لديك نسخة منه، فاعمل على ملف مُطابق وتحقق من صحة المُخرجات قبل استخدامها.
تقسيم السجلات باستخدام بايثون
يقرأ بايثون المستند xml.etree.ElementTree.iterparse()تدريجيًا، مما يتجنب تحميل شجرة XML بأكملها في الذاكرة دفعة واحدة. يقوم البرنامج النصي أدناه بتجميع العناصر الفرعية المباشرة في دفعات، ثم يكتب كل دفعة داخل نسخة جديدة من الوسم الجذر الأصلي وخصائصه. لا يحتاج هذا البرنامج إلى أي حزمة خارجية. إذا لم يكن بايثون مثبتًا، فاستخدم التنزيلات الرسمية لبايثون لنظام ويندوز ؛ وتصف وثائق ElementTree المحلل المستخدم هنا.
احتفظ بالملف الأصلي دون تغيير، واختر مجلد إخراج جديدًا وفارغًا لكل عملية تشغيل.
أنشئ نسخة عمل من ملف XML المصدر. أنشئ مجلد إخراج جديد فارغ، مثل parts.
في محرر نصوص عادي، احفظ ما يلي split_xml.pyفي نفس مجلد العمل الخاص بالنسخة.
from pathlib import Path
import sys
import xml.etree.ElementTree as ET
source = Path(sys.argv[1])
out_dir = Path(sys.argv[2])
records_per_file = int(sys.argv[3]) if len(sys.argv) > 3 else 500
if records_per_file < 1:
raise SystemExit("records_per_file must be at least 1")
out_dir.mkdir(parents=True, exist_ok=True)
if any(out_dir.glob("part_*.xml")):
raise SystemExit("Choose a new, empty output folder first")
records = []
part_count = 0
root = None
root_tag = None
root_attrib = {}
def write_part(items, number):
wrapper = ET.Element(root_tag, root_attrib)
wrapper.extend(items)
target = out_dir / f"part_{number:04d}.xml"
ET.ElementTree(wrapper).write(
target, encoding="utf-8", xml_declaration=True
)
depth = 0
for event, elem in ET.iterparse(source, events=("start", "end")):
if event == "start":
depth += 1
if depth == 1:
root = elem
root_tag = elem.tag
root_attrib = dict(elem.attrib)
else:
if depth == 2:
records.append(elem)
if len(records) == records_per_file:
part_count += 1
write_part(records, part_count)
records.clear()
root[:] = []
depth -= 1
if records:
part_count += 1
write_part(records, part_count)
if part_count == 0:
raise SystemExit("No direct-child elements were found under the root")
print(f"Wrote {part_count} files.")
شغّل الأمر
افتح برنامج PowerShell في مجلد العمل وتأكد من توفر Python. الوسيط الأخير هو عدد السجلات لكل جزء؛ القيمة الافتراضية هي 500 إذا لم تقم بتحديدها.
python --version
python split_xml.py input.xml parts 500
في نظام ويندوز المُثبّت باستخدام مُشغّل بايثون، يمكن أن يكون السطر الثاني كالتالي py -3 split_xml.py input.xml parts 500: . يقوم البرنامج النصي بكتابة ملفات مثل part_0001.xmlويُبلغ عن عددها. استخدم مجلد إخراج فارغًا في كل مرة؛ يتوقف البرنامج النصي إذا كانت ملفات الأجزاء المطابقة موجودة بالفعل، حتى لا يخلط التشغيل الجديد مع الملفات المتبقية دون علم المستخدم.
تحدد وسيطة الأمر الثالثة عدد السجلات، وليس الحد الأقصى المضمون لحجم الملف.
تحقق من النتائج قبل الاستيراد
أولاً، قم بتحليل كل جزء مُنشأ لاكتشاف ملفات XML غير الصحيحة. من PowerShell، قم بتشغيل ما يلي:
python -c "import glob, xml.etree.ElementTree as ET; files=glob.glob('parts/*.xml'); [ET.parse(p) for p in files]; print(f'{len(files)} files parsed')"
تأكد من أن العدد المُبلغ عنه ليس صفرًا، وافحص بعض الملفات، وقارن إجمالي عدد السجلات مع المصدر. يُثبت التحليل الناجح فقط أن جزءًا ما سليم البنية ، ولا يُثبت استيفائه لمعايير مخطط XML (XSD) أو تعريف نوع المستند (DTD) أو قواعد العمل أو متطلبات التطبيق الذي سيستخدمه. عندما يكون ذلك مهمًا، تحقق من صحة كل جزء باستخدام المخطط أو أداة التحقق التي يستخدمها النظام المستهدف. تشرح موارد W3C XML Schema الدور المنفصل لقيود المخطط.
قم بتحليل كل جزء للتأكد من سلامته، ثم قم بتشغيل مخطط التطبيق أو عمليات التحقق من الاستيراد بشكل منفصل.
الحدود والحلول السريعة
لا يزال أحد الأجزاء كبيرًا جدًا: قلل عدد السجلات، على سبيل المثال من 500 إلى 100. قد يتسبب سجل واحد كبير في تجاوز أحد الأجزاء لحجمك المستهدف؛ لا يفرض هذا البرنامج النصي حدًا أقصى صارمًا للميغابايت.
تفشل الأجزاء في التحقق من صحة المخطط: تحقق من أن حدود السجل المختارة تتطابق مع البنية والترتيب المطلوبين في المخطط. يمكن أن يحافظ التقسيم على التداخل السليم دون الحفاظ على صحة المستند على مستوى المستند.
تم تغيير البادئات أو التنسيق: قد يقوم ElementTree بتسلسل بادئات مساحات الأسماء بشكل مختلف، كما يقوم بتطبيع تمثيل XML. قارن القيم المُحللة وسلوك التطبيق بدلاً من توقع نسخ متطابقة بايتًا ببايت.
يستخدم المصدر تعريفات أنواع المستند (DTDs) والتعليقات وتعليمات المعالجة أو البيانات الوصفية على مستوى الجذر: لا يحافظ هذا البرنامج النصي البسيط على جميع بنيات المستند. استخدم أداة XML تدعم المصطلحات واختبر على نسخة منها.
بالنسبة لقائمة منتظمة من السجلات المستقلة، يوفر لك هذا الأسلوب ملفات قابلة للإدارة والتحليل بشكل منفصل دون الإخلال ببنية الملفات الأصلية والفرعية. يحدد هيكل السجل وقواعد التحقق من صحة الوجهة ما إذا كانت الأجزاء الناتجة صالحة أيضًا لسير عملك.