كيفية قراءة ملف XML كبير دون تحميله في الذاكرة واستخدام Xelement
-
20-09-2019 - |
سؤال
أريد قراءة ملف XML كبير (100 + م). نظرا لحجمها، لا أريد تحميله في الذاكرة باستخدام Xelement. أنا أستخدم استعلامات LinQ-XML لتحليلها وقراءتها.
ما هي أفضل طريقة للقيام بذلك؟ أي مثال على مزيج من XPath أو xmlReader مع LinQ-XML / Xelement؟
الرجاء المساعدة. شكرًا.
المحلول
نعم، يمكنك الجمع بين xmlreader مع الطريقة xnode.readfrom., ، راجع المثال في الوثائق التي تستخدم C # لعالج العقد بشكل انتقائي الموجود بواسطة XMLReader كإعادة.
نصائح أخرى
رمز المثال في وثائق MSDN ل XNode.ReadFrom
الطريقة كما يلي:
class Program
{
static IEnumerable<XElement> StreamRootChildDoc(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "Child")
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
break;
}
}
}
}
static void Main(string[] args)
{
IEnumerable<string> grandChildData =
from el in StreamRootChildDoc("Source.xml")
where (int)el.Attribute("Key") > 1
select (string)el.Element("GrandChild");
foreach (string str in grandChildData)
Console.WriteLine(str);
}
}
لكنني وجدت أن StreamRootChildDoc
يجب تعديل الطريقة في المثال على النحو التالي:
static IEnumerable<XElement> StreamRootChildDoc(string uri)
{
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent();
// Parse the file and display each of the nodes.
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element && reader.Name == "Child")
{
XElement el = XElement.ReadFrom(reader) as XElement;
if (el != null)
yield return el;
}
else
{
reader.Read();
}
}
}
}
ضع في اعتبارك أنك سيتعين عليك قراءة الملف بالتتابع والإشارة إلى الأشقاء أو أحفاد سيكون بطيئا في أحسن الأحوال ومستحيلة في أسوأ الأحوال. خلاف ذلك martinhonnn لديه المفتاح.