来自另一个大型XML文件的新XML文件,使用未知元素更改内部数据

时间:2016-02-19 01:08:02

标签: c# xml

我有一个非常大的(~1GB)XML文件。我需要解析它,找到特定节点,更改这些节点中的数据,然后将其全部写入新的XML文件。这是一个问题 - 有很多我不关心的因素 - 我甚至都不知道它们是什么 - 但它们也需要被复制。

This所以帖子建议我使用XmlReader,这样我就不必将整个输入文件加载到内存中。该问题有this回答,建议使用ReadToDescendant方法。这几乎可以满足我的需要,但问题是我在读取"读取的节点之前丢失了所有XML。不知何故,我需要将刚读过的所有内容复制到新文件中。我不在乎那里有什么,只需要逐字复制。

This SO帖子会起作用(还有其他几个人喜欢它),除了它使用XmlDocument,如果我没有弄错的话,它将首先将整个内容加载到内存中。虽然这对小文件来说很好,但我想在这里避免这种情况。

对于视觉类型,我们想知道我想做什么:

<root>
 <SomeNodeUndefinedAtDesignTime>
    <ThisNodeHasSubNodes>
        <WhichHasSubNodes_Etc/>
    </ThisNodeHasSubNodes>
 </SomeNodeUndefinedAtDesignTime>
 <AnotherUndefinedNode>
    <!--Similar to the first, who knows what all is in here-->
 </AnotherUndefinedNode>
 <!-- There may be dozens or even hundreds of these -->
 <ANodeIAmInterestedIn>
    Old data to be replaced
 </ANodeIAmInterestedIn>
 <ANodeIAmInterestedIn>
    More data to be replaced
 </ANodeIAmInterestedIn>
 <YetAnotherUndefinedNode>
    <!-- stuff -->
 </YetAnotherUndefinedNode>
</root>

我想接受输入然后输出:

<root>
 <SomeNodeUndefinedAtDesignTime>
    <ThisNodeHasSubNodes>
        <WhichHasSubNodes_Etc/>
    </ThisNodeHasSubNodes>
 </SomeNodeUndefinedAtDesignTime>
 <AnotherUndefinedNode>
    <!--Similar to the first, who knows what all is in here-->
 </AnotherUndefinedNode>
 <!-- There may be dozens or even hundreds of these -->
 <ANodeIAmInterestedIn>
    Here is my new data
 </ANodeIAmInterestedIn>
 <ANodeIAmInterestedIn>
    Here is more new data
 </ANodeIAmInterestedIn>
 <YetAnotherUndefinedNode>

    <!-- stuff -->
 </YetAnotherUndefinedNode>
</root>

有没有办法

  1. 以流形式阅读文件,以便我不必一次将整个内容加载到内存中
  2. 复制在设计时未定义的元素
  3. 更改特定元素中的数据
  4. 将结果写入新文件

1 个答案:

答案 0 :(得分:4)

您可以创建一个XmlWriterpublic void CopyTo(XmlReader reader, XmlWriter writer, Dictionary<string, string> replacements) { var currentElementName = ""; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: currentElementName = reader.Name; writer.WriteStartElement(reader.Name); //Copy all attributes verbatim if (reader.HasAttributes) writer.WriteAttributes(reader, true); //Handle empty elements by telling the writer to close right away if (reader.IsEmptyElement) writer.WriteEndElement(); break; case XmlNodeType.EndElement: currentElementName = ""; writer.WriteEndElement(); break; case XmlNodeType.Text: if (replacements.ContainsKey(currentElementName)) writer.WriteString(replacements[currentElementName]); else writer.WriteString(reader.Value); break; case XmlNodeType.Whitespace: writer.WriteWhitespace(reader.Value); break; //Other cases. Attributes, comments etc. } writer.Flush(); } } 的方法,该方法可以完全按照您的意愿进行操作。

innerText

这是一个简单的例子,它不会处理属性和其他一些人员,但它可以很好地处理元素 它将复制xml结构和所有元素,并将var xmlReader = XmlReader.Create(File.OpenRead("inputFilePath")); var xmlWriter = XmlWriter.Create(File.OpenWrite("outputFilePath")); var replacements = new Dictionary<string, string> { ... }; CopyTo(xmlReader, xmlWriter, replacements); 替换为已知元素。

用法:

async

此外,如果您想要在读取大型元素时执行有用的操作,则可以使用XmlReader版本的header方法。