我正在尝试阅读2.5GB XML文件并删除某些节点,比如说,“CD”元素和“DVD”元素。目前我正在做这样的事情:
using (XmlReader reader = XmlReader.Create("file.xml"))
{
DeleteElements(reader.ReadElements("CD"));
DeleteElements(reader.ReadElements("DVD")); // reader returns 0 elements
}
注意:DeleteElements
只是循环这些元素并将其从文档中删除,但对于此问题而言,这主要是不重要的。
目前我发现没有检索到“DVD”元素。如果您之前使用过XmlReader
,我相信您可以在此处找出问题的原因:读者在读取“CD”节点的文档后,读者找不到任何“DVD” “元素因为读者位于文档的末尾。
考虑到XML文件的大小以及我想要检索的元素数量,我无法将整个文档加载到内存中,因为你得到OutOfMemoryException
- 这意味着没有XDocument或XPathDocument善良。
有没有办法让XmlReader在读取文档时返回“CD”和“DVD”?最初加载文档非常耗时,所以我不想多次这样做。像reader.ReadElements("DVD|CD")
这样令人敬畏的东西将是 sweet 。
答案 0 :(得分:2)
XmlReader是一个仅向前xml解析器。如果有一个ReadElements方法,它会将读者运行到最后,然后就不再有DVD元素了。所以你必须在文件上运行两次。
XmlReader的基本用法:
using (XmlReader reader = XmlReader.Create("input.xml")) {
while (reader.Read()) {
switch (reader.NodeType) {
case XmlNodeType.Element:
switch (reader.Name) {
case "CD":
// do something with a CD
break;
case "DVD":
// do something with a DVD
break;
default:
// do something with all other elements
break;
}
break;
}
}
}
您在DeleteElements方法中做了什么?您可能需要为新的临时文件创建一个XmlWriter,然后将除之外的所有元素删除写入临时文件,并至少替换带有临时文件的原始文件。
通过这种方式,您可以对所有元素进行一次循环,包括删除(排除)某些元素。