从API获取XML并将其存储在本地的最有效方法是什么?
本文关键字:有效 方法 是什么 XML 获取 API 存储 | 更新日期: 2023-09-27 18:01:18
我试图找到从韦氏词典中读取XML的最快方法,并将其存储到本地文件中以供以后使用。下面,我尝试实现一个模块,它做几件事:
- 从本地目录读取2000个单词
- 使用API 在merriam字典中查找每个单词
- 将定义存储在本地XML中以供以后使用。
我不确定制作XML是否是存储这些数据的最佳方式,但它似乎是最简单的事情。起初,我想我会用不同的步骤来做。(1. 查找单词,存储单词和定义到数据结构中。2. 将所有数据转储为XML。)然而,这带来了一个问题,因为要在运行时(调用)堆栈上存储太多的东西。
因此,在这种情况下,我试图通过查找每个单词然后逐个保存到xml来加快速度。然而,这也是一个缓慢的方法。每写500-600字要花我10分钟。
public void load_module() // stores words/definitions into xml file
{ // 1. Pick up word from text file 2. Look up word's definition 3. Store in Xml
string workdirect = Directory.GetCurrentDirectory();
workdirect = workdirect.Substring(0, workdirect.LastIndexOf("bin"));
workdirect += "words1.txt";
using (StreamReader read = new StreamReader(workdirect)) // 1. Pick up word from text file
{
while (!read.EndOfStream)
{
string line = read.ReadLine();
var definitions = load(line.ToLower()); // 2. Retrieve Words Definitions
store_xml(line, definitions);
wordlist.Add(line);
}
}
}
public List<string> load(string word)
{
XmlDocument doc = new XmlDocument();
List<string> definitions = new List<string>();
XmlNodeList node = null;
doc.Load("http://www.dictionaryapi.com/api/v1/references/collegiate/xml/"+word+"?key=*****************"); // Asteriks to hide the actual API key
if (doc.SelectSingleNode("entry_list").SelectSingleNode("entry").SelectSingleNode("def") == null)
{
return definitions;
}
node = doc.SelectSingleNode("entry_list").SelectSingleNode("entry").SelectSingleNode("def").SelectNodes("dt");
// TO DO : implement definitions if there is no node "def" in first node entry "entry_list"
foreach (XmlNode item in node)
{
definitions.Add(item.InnerXml.ToString().ToLower());
}
return definitions;
}
public void store_xml(string word, List<string> definitions)
{
string local = Directory.GetCurrentDirectory();
string name = "dictionary_word.xml";
local = local.Substring(0, local.LastIndexOf("bin"));
bool exists = File.Exists(local + name);
if (exists)
{
XmlDocument doc = new XmlDocument();
doc.Load(local + name);
XmlElement wordindoc = doc.CreateElement("Word");
wordindoc.SetAttribute("xmlns", word);
XmlElement defs = doc.CreateElement("Definitions");
foreach (var item in definitions)
{
XmlElement def = doc.CreateElement("Definition");
def.InnerText = item;
defs.AppendChild(def);
}
wordindoc.AppendChild(defs);
doc.DocumentElement.AppendChild(wordindoc);
doc.Save(local+name);
}
else
{
using (XmlWriter writer = XmlWriter.Create(@local + name))
{
writer.WriteStartDocument();
writer.WriteStartElement("Dictionary");
writer.WriteStartElement("Word", word);
writer.WriteStartElement("Definitions");
foreach (var def in definitions)
{
writer.WriteElementString("Definition", def);
}
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
}
}
当处理需要导出为XML的大量数据时,我通常会将数据作为自定义对象的集合保存在内存中,而不是作为XMLDocument:
public class Definition
{
public string Word { get; set; }
public string Definition { get; set; }
}
然后我将使用XMLWriter将集合写入XML文件:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = (" ");
settings.Encoding = Encoding.UTF8;
using (XmlWriter writer = XmlWriter.Create("C:'output'output.xml", settings))
{
writer.WriteStartDocument();
// TODO - use XMLWriter functions to write out each word and definition
writer.Flush();
}
如果你仍然缺少内存,你可以分批地写出XML(例如每500个定义)。
我发现Microsoft关于改进XML性能的文章是一个非常有用的参考,特别是关于设计注意事项的部分。