编辑大型 XML 文件 [英] Edit a large XML file

查看:44
本文介绍了编辑大型 XML 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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.

以该答案为基础,从中获取XmlReaderExtensionsXmlWriterExtensionsXmlStreamingEditorBaseXmlStreamingEditor 类并将 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 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆