如何使用C#.NET合并Blob中同格式XML文件并写入目标Blob
问题
我有一个Blob存储(XYZ)会接收多个格式相同的XML文件,示例如下:
- XML文件1:
<Product><ID>001</ID><Name>John</Name><Designation>Developer</Designation></Product> - XML文件2:
<Product><ID>002</ID><Name>Peter</Name><Designation>Tester</Designation></Product> - XML文件3:
<Product><ID>003</ID><Name>Arun</Name><Designation>Support</Designation></Product> - XML文件4:
<Product><ID>004</ID><Name>Swetha</Name><Designation>Analyst</Designation></Product> - XML文件5:
<Product><ID>005</ID><Name>Gokul</Name><Designation>Maintainence</Designation></Product>
需要将这些文件合并为单个XML文件,结构如下,并写入另一个Blob存储(ABC):
<xml> <Product><ID>001</ID><Name>John</Name><Designation>Developer</Designation></Product> <Product><ID>002</ID><Name>Peter</Name><Designation>Tester</Designation></Product> <Product><ID>003</ID><Name>Arun</Name><Designation>Support</Designation></Product> <Product><ID>004</ID><Name>Swetha</Name><Designation>Analyst</Designation></Product> <Product><ID>005</ID><Name>Gokul</Name><Designation>Maintainence</Designation></Product> </xml>
我目前尝试的代码如下:
using (var jw = new XmlTextWriter(sw)) //sw holds the o/p location to store the merged files { jw.WriteStartElement("root"); int i = 0; int c = list.Count(); foreach (var item in list) { if (i > 0) await jw.WriteRawAsync("\r\n"); var blobdata = await OutputContainerService.GetContentAsync(input.InputLocation + "/" + item); await jw.WriteRawAsync(blobdata); i++; } jw.WriteEndElement(); await jw.FlushAsync(); }
请问如何使用C# .NET实现该需求?
回答
你的代码思路没问题,但直接用WriteRawAsync有个隐患:如果单个XML文件带了<?xml version="1.0"?>声明,拼出来的最终XML会无效。另外你现在写的根元素是root,需求里是xml,得改一下。下面给你两种靠谱的实现方式:
方式一:用XDocument(简洁易维护)
这种方式会先解析每个XML片段,确保结构合法,再合并到根元素里,不用担心格式问题:
// 创建目标根元素 var rootElement = new XElement("xml"); foreach (var fileName in list) { // 从Blob读取XML内容 var xmlContent = await OutputContainerService.GetContentAsync($"{input.InputLocation}/{fileName}"); // 解析成XElement,自动忽略XML声明 var productNode = XElement.Parse(xmlContent); // 添加到根元素下 rootElement.Add(productNode); } // 把合并后的XML写入目标Blob var mergedXml = rootElement.ToString(); await targetBlob.UploadTextAsync(mergedXml);
方式二:优化你的XmlWriter实现(适合大文件流式处理)
如果要处理的文件很多、体积大,用流式的XmlWriter更省内存,调整后的代码如下:
// 直接打开目标Blob的写入流,不用先存到内存里 using (var outputStream = await targetBlob.OpenWriteAsync(true)) using (var xmlWriter = XmlWriter.Create(outputStream, new XmlWriterSettings { Indent = true, // 可选:让输出的XML更整齐 OmitXmlDeclaration = true // 不需要单独的XML声明 })) { xmlWriter.WriteStartElement("xml"); foreach (var fileName in list) { var xmlContent = await OutputContainerService.GetContentAsync($"{input.InputLocation}/{fileName}"); // 解析XML片段,过滤掉可能的声明 using (var stringReader = new StringReader(xmlContent)) using (var xmlReader = XmlReader.Create(stringReader)) { // 跳过XML声明节点(如果存在) if (xmlReader.NodeType == XmlNodeType.XmlDeclaration) { xmlReader.Read(); } // 把<Product>节点复制到输出 xmlWriter.WriteNode(xmlReader, true); } } xmlWriter.WriteEndElement(); await xmlWriter.FlushAsync(); }
几个关键提醒
- 别直接写Raw内容:直接拼XML字符串很容易出格式错误,用XML解析类处理能保证最终XML是合法的。
- 根元素名称要对应:确保根元素是需求里的
xml,不是你原来写的root。 - 大文件选流式处理:如果文件量大,优先用XmlWriter的方式,避免把所有内容都加载到内存里导致性能问题。
内容的提问来源于stack exchange,提问作者Black Pearl
相关产品推荐
相关产品推荐

