我有一个非常大的(~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>
有没有办法
答案 0 :(得分:4)
您可以创建一个XmlWriter
和public 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
方法。