使用 XMLReader 解析大 XML 文件
Posted
技术标签:
【中文标题】使用 XMLReader 解析大 XML 文件【英文标题】:Parse Big XML file using XMLReader 【发布时间】:2020-08-19 18:17:06 【问题描述】:我有一个非常大的 xml 文件,格式如下
<ABC>
<NAMEDETAILS></NAMEDETAILS>
<PRODUCT>
<PRODUCTDETAILS>
<ProductName>
<name>Car</Name>
<name>lorry<name>
<name>Car<name>
</ProductName>
</PRODUCTDETAILS>
<PRODUCTDETAILS>
<ProductName>
<name>van</Name>
<name>cycle</Name>
<name>bus</Name>
</ProductName>
</PRODUCTDETAILS>
<PRODUCTDETAILS>
<ProductName>
<name>car</Name>
<name>cycle</Name>
<name>bus</Name>
</ProductName>
</PRODUCTDETAILS>
<PRODUCT>
</ABC>
我想检索名称标签值为“car”的 PRODUCTDETAILS 数据,并将其保存在一个新的 xml 文件中。我正在使用 XMLReader,但我一直在前进。有人可以帮助我。下面是c#代码
XMLReader xmlReader = XMLReader.Create(@"\\Drive\xmlfile.xml")
while (xmlReader.Read())
If (xmlReader.NodeType == XMLNodeType.Element) && (xmlReader.Name == "PRODUCTDETAILS")
xmlReader.ReadtoDescendant("ProductName")
【问题讨论】:
【参考方案1】:using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace ConApp1
class Program
static void Main()
using (var xmlWriter = XmlWriter.Create("result.xml"))
using (var xmlReader = XmlReader.Create("test.xml"))
xmlWriter.WriteStartElement("PRODUCT");
while (xmlReader.ReadToFollowing("PRODUCTDETAILS"))
using (var nodeReader = xmlReader.ReadSubtree())
nodeReader.MoveToContent();
var elem = (XElement)XNode.ReadFrom(nodeReader);
var name = elem.Descendants("name").First().Value;
if (name.Equals("car", StringComparison.OrdinalIgnoreCase))
elem.WriteTo(xmlWriter);
既然你说文件很大,那么读写都应该使用流式工具来完成。 XmlWriter
用于写作。这保证了低内存消耗并且不会出现OutOfMemoryException
。
【讨论】:
【参考方案2】:尝试以下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
class Program
const string INPUT_FILENAME = @"c:\temp\test.xml";
const string OUTPUT_FILENAME = @"c:\temp\test1.xml";
static void Main(string[] args)
XmlReader reader = XmlReader.Create(INPUT_FILENAME);
string header = "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Cars></Cars>";
XDocument doc = XDocument.Parse(header);
XElement cars = doc.Root;
while (!reader.EOF)
if (reader.Name != "PRODUCTDETAILS")
reader.ReadToFollowing("PRODUCTDETAILS");
if (!reader.EOF)
XElement product = (XElement)XElement.ReadFrom(reader);
if(product.Descendants("name").Any(x => ((string)x).Trim() == "Car"))
cars.Add(product);
doc.Save(OUTPUT_FILENAME);
【讨论】:
我可以得到 xelement。但是每个 ProductName 都有很多名称标签。如果我使用 FirstOrDefault() 我只会得到第一个值。我想知道 ProductName 中的至少一个名称标签是否具有值“car”。如果是,我希望将特定的 ProductDetails 数据作为一个整体放在一个单独的 xml 文件中@jdwengspan>以上是关于使用 XMLReader 解析大 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 XMLreader 读取和解析大型 XML 文件。空值问题
使用XDocument.Load(xmlreader)方法?