2

我有一个问题,我正在处理相当长的一段时间。我有一个包含超过 50000 条记录的 XML 文件(一条记录有 3 个级别)。我的一个应用程序使用此文件来控制文档发送(该记录包含必须发送给某个人的文档类型等信息)。因此,在我的应用程序中,我将 XML 文件加载到 XmlDocument 中,然后使用 SelectNodes 方法创建一个 XmlNodeList,从中读取我想要的数据。过程是这样的——我们的工人拿人的身份证(简单的条形码)并用条形码阅读器读取它。读取条形码值后,我的应用程序会在 XML 文件中找到具有该 ID 的人员,并将文档的类型存储到字符串变量中。然后工人拿起文件并读取其条形码,如果文档条形码的值与字符串变量中的值匹配,则应用程序记录类型为xxxxxxxx的文档将被发送给ID为yyyyyyyyy的人。这是非常简单的代码,它现在可以完美运行,它的外观是这样的: 在 textBox1_TextChanged 事件上(工作人员读取人员 ID):

foreach(XmlNode node in NodeList){
if(String.Compare(node.Attributes.GetNamedItem("ID").Value.ToString(),textBox1.Text)==0)
{
 ControlString = node.ChildNode[3].FirstChild.Attributes.GetNamedItem("doctype").Value.ToString();
 break;
}
}
textBox2.Focus();

在 textBox2_TextChanged 事件上(工作人员读取文档条码):

if(String.Compare(textBox2.Text,ControlString)==0)
{
//Create a record and insert it into a SQL database
}

我的问题是 - 我的应用程序将如何处理更大的 XML 文件(我被告知 XML 文件可能多达 500,000 条记录),这种方法是否有效,或者我需要将文件切割成更小的文件。如果我必须削减它,请给我一些代码示例的想法,我尝试这样做:读取整个记录并将其存储到字符串中:

private void WriteXml(XmlNode record)
        {
            tempXML = record.InnerXml;
            temp = "<" + record.Name + " code=\"" + record.Attributes.GetNamedItem("code").Value + "\">" + Environment.NewLine;
            temp += tempXML + Environment.NewLine;
            temp += "</" + record.Name + ">";
            SmallerXMLDocument += temp + Environment.NewLine;
            temp = "";
            i++;
        }

tempXML、temp 和 SmallerXMLDocument 都是字符串变量。

然后在 button_Click 方法中,我将 XML 文件加载到 XmlNodeList 中(再次使用 XmlDocument.SelectNodes 方法),并尝试创建一个大字符串值来保存所有记录,如下所示:

foreach(XmlNode node in nodes)
{
 if(String.Compare(node.ChildNode[3].FirstChild.Attributes.GetNamedItem("doctype").Value.ToString(),doctype1)==0)
{
  WriteXML(node);
}
}

我的想法是创建一个字符串值(在本例中称为 SmallerXmlDocument),当我通过整个 XML 文件时,只需将该字符串的值复制到一个新文件中。这有效,但仅适用于最多包含 2000 条记录的文件(我的记录不止这些)。那么,如果我需要将文件切割成更小的部分,最好的方法是什么(请记住,XML 文件中可能有多达 50 万条记录)?

谢谢

4

2 回答 2

2

首先,我怀疑您在滥用 XML API。您可以使用XPath直接查询XmlDocument以立即获得结果,而无需先选择记录列表并对其进行迭代。在任何时候都不需要将部分 XML 树转换为字符串。

只要您不介意在应用程序上花费 50 到 500 兆字节的 RAM,将整个 XML 文档加载到内存中的方法就可以正常工作。

如果您想节省 RAM,您应该使用XmlReader从磁盘流式传输 XML。

于 2012-07-04T09:26:48.533 回答
0

What it comes down to is you need to access the data, so whether it's 50,000 rows in 1 file, or 1000 rows in 50 files, you've got the same amount of data.

There's nothing stopping you using something SQL-Lite or SQL Server Compact in your client. There are many benefits to this. You could use XMLReader to parse the data into tables in your DB. Having done that, you can now use the SQL Engine to find the rows you need, using joins to find the related rows much easier. You're also not storing vast amounts of data in memory. If the XML might change, then watch the file for changes & refresh the DB when it does.

于 2012-07-04T09:59:12.930 回答