您可以做的是采用 Mark Fussell 的文章 Combining the XmlReader and XmlWriter classes for simple streaming transformations 中将 XmlReader 流式传输到 XmlWriter 的基本逻辑,将您的 3GB 文件转换为修改后的文件,其中 <alias> 节点已被重新定位到<name> 节点。 this answer 到 Automating replacing tables from external files 中给出了使用这种流转换的示例。
使用该答案作为基础,从中获取 XmlReaderExtensions、XmlWriterExtensions、XmlStreamingEditorBase 和 XmlStreamingEditor 类并创建 XmlStreamingEditor 的子类以创建 CustomerAliasXmlEditor,如下所示:
class CustomerAliasXmlEditor : XmlStreamingEditor
{
// Confirm that the <customer> element is not in any namespace.
static readonly XNamespace customerNamespace = "";
public static void TransformFromTo(string fromFilePath, XmlReaderSettings readerSettings, string toFilePath, XmlWriterSettings writerSettings)
{
using (var xmlReader = XmlReader.Create(fromFilePath, readerSettings))
using (var xmlWriter = XmlWriter.Create(toFilePath, writerSettings))
{
new CustomerAliasXmlEditor(xmlReader, xmlWriter).Process();
}
}
public CustomerAliasXmlEditor(XmlReader reader, XmlWriter writer)
: base(reader, writer, ShouldTransform, Transform)
{
}
static bool ShouldTransform(XmlReader reader)
{
return reader.GetElementName() == customerNamespace + "customer";
}
static void Transform(XmlReader from, XmlWriter to)
{
var customer = XElement.Load(from);
var alias = customer.Element(customerNamespace + "alias");
if (alias != null)
{
var name = customer.Element(customerNamespace + "name");
if (name == null)
{
name = new XElement(customerNamespace + "name");
customer.Add(name);
}
alias.Remove();
name.Add(alias);
}
customer.WriteTo(to);
}
}
如果fromFileName 是您当前的 3GB XML 文件的名称,toFileName 是输出转换后的 XML 的文件的名称,您可以这样做:
var readerSettings = new XmlReaderSettings { IgnoreWhitespace = true };
var writerSettings = new XmlWriterSettings { Indent = false}; // Or true if you prefer.
CustomerAliasXmlEditor.TransformFromTo(fromFileName, readerSettings, toFileName, writerSettings);
工作示例.Net fiddle 显示 XML
<Root>
<Item>
<SubItem>
<customer>
<name><first>Robert</first></name>
<alias>Rob</alias>
</customer>
</SubItem>
</Item>
<Item>
</Root>
转化为
<Root>
<Item>
<SubItem>
<customer>
<name>
<first>Robert</first>
<alias>Rob</alias>
</name>
</customer>
</SubItem>
</Item>
<Item>
</Root>