Modifying XML file in-place?

北战南征 提交于 2020-01-02 05:45:17

问题


Suppose I have the following XML File:

<book>
 <name>sometext</name>
 <name>sometext</name>
 <name>sometext</name>
 <name>Dometext</name>
 <name>sometext</name>
</book> 

If I wanted to modify the content by changing D to s (As shown in the fourth "name" node) without having to read/write the entire file, would this be possible?


回答1:


A 10 MB file is not a problem. Slurp it up. Modify the DOM. Write it back to the filesystem. 10 GB is more of a problem. In that case:

Assumption: You are not changing the length of the file. Think of the file as an array of characters and not a (linked) list of characters: You cannot add characters in the middle, only change them.

You need to seek the position in the file to change and then write that character to disk.

In the .NET world, with a FileStream object, you what to set the Position attribute to the index of the D character and then write a single s character. Check out this question on random access of text files.

Also read this question: How to insert characters to a file using C#. It looks like you can't really use the FileStream object, but instead will have to resort to writing individual bytes.

Good luck. But really, if we are only talking 10 MB, then just slurp it up. The computer should be doing your work.




回答2:


I would just read in the file, process, and spit it back out.

This can be done in a streaming fashion with XmlReader -- it's more manual work than XmlDocument or XDocument, but it does avoid creating an in-memory DOM (XmlDocument/XDocument can be used with this same read/write pattern, but generally require the full reconstruction in-memory):

  1. Open file input file stream (XmlReader)
  2. Open output file stream (XmlWriter, to a different file)
  3. Read from XmlReader and write to XmlWriter performing any transformations as neccessary.
  4. Close streams
  5. Move new file to old file (overwrite, an atomic action)

While this can be setup to process input and output on the same open file with a bunch of really clever work nothing will be saved and there any many edge cases including increasing on decreasing file lengths. In fact, it might be slower to try and simply shift the contents of a file backwards to fill in gaps or shift the file contents forward to make new room. The filesystem cache will likely make any "gains" minimal/moot for anything but the most basic length-preserving operation. In addition, modifying a file in place is not an atomic action and is generally non-recoverable in case of an error: at the expense of a temporary file, the read/write/move approach is atomic wrt the final file contents.

Or, consider XSLT -- it was designed for this ;-)

Happy coding.




回答3:


The cleanest (and best) way would be to use the XmlDocument object to manipulate, but a quick and dirty solution is to just read the XML to a string and then:

xmlText = xmlText.Replace("Dometext", "sometext");



回答4:


An XML file is a text file and does not allow for insertion/deletions. The only mutations supported are OverWrite and Append. Not a good match for XML.

So, first make very sure you really need this. It's a complicated operation, only worth it on very large files.

Since there could be a change in length you will at least have to move everything after the first replacement. The possibility of multiple replacements means you may need a big buffer to accommodate the changes.

It's easier to copy the whole file. That is expensive in I/O but you save on memory use.



来源:https://stackoverflow.com/questions/7751260/modifying-xml-file-in-place

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!