问题描述
我有一个 3GB 的 XML 文件.我需要将节点移动为另一个节点的子节点.将大文件加载为 XmlDocument
效率不高.我看到 XmlReader
是另一种方法,但不确定它在我的场景中将如何工作以及我应该使用哪些其他类来执行此操作.
I have a 3GB XML file. I need to move nodes as child node of another. Loading large file as XmlDocument
is not efficient. I see XmlReader
is another approach but not sure exactly how it will work in my scenario and what other classes I should be using to do this.
我需要将所有别名节点移动到其相关的客户>名称节点.
I need to move all alias node to its related customer>name node.
<customer>
<name><first>Robert</first></name>
<alias>Rob</alias>
</customer>
推荐答案
你可以做的是将 XmlReader
从 Mark 流式传输到 XmlWriter
的基本逻辑Fussell 的文章 结合 XmlReader 和 XmlWriter 类进行简单的流转换 将您的 3GB 文件转换为修改后的文件,其中 节点已重新定位到
节点.这个答案中给出了使用此类流式转换的示例,从外部文件自动替换表格.
What you can do is to take the basic logic of streaming an XmlReader
to an XmlWriter
from Mark Fussell's article Combining the XmlReader and XmlWriter classes for simple streaming transformations to transform your 3GB file into a modified file in which the <alias>
nodes have been relocated to the <name>
nodes. An example of using such streaming transformations is given in this answer to Automating replacing tables from external files.
以该答案为基础,从中获取XmlReaderExtensions
、XmlWriterExtensions
、XmlStreamingEditorBase
和XmlStreamingEditor
类并将 XmlStreamingEditor
子类化以创建 CustomerAliasXmlEditor
,如下所示:
Using that answer as a basis, grab the classes XmlReaderExtensions
, XmlWriterExtensions
, XmlStreamingEditorBase
and XmlStreamingEditor
from it and subclass XmlStreamingEditor
to create CustomerAliasXmlEditor
as follows:
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 的文件的名称,您可以执行以下操作:
Then if fromFileName
is the name of your current 3GB XML file and toFileName
is the name of the file to which to output the transformed XML, you can do:
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
Sample working .Net fiddle showing that the 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>
这篇关于编辑大型 XML 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!