I wrote a tool to repair some XML files (i.e., insert some attributes/values that were missing) using C# and Linq-to-XML. The tool loads an existing XML file into an XDocument object. Then, it parses down through the node to insert the missing data. After that, it calls XDocument.Save() to save the changes out to another directory.
All of that is just fine except for one thing: any 
 entities that are in the text in the XML file are replaced with a new line character. The entity represents a new line, of course, but I need to preserve the entity in the XML because another consumer needs it in there.
Is there any way to save the modified XDocument without losing the 
 entities?
Thank you.
The

entities are technically called “numeric character references” in XML, and they are resolved when the original document is loaded into theXDocument. This makes your issue problematic to solve, since there is no way of distinguishing resolved whitespace entities from insignificant whitespace (typically used for formatting XML documents for plain-text viewers) after theXDocumenthas been loaded. Thus, the below only applies if your document does not have any insignificant whitespace.The
System.Xmllibrary allows one to preserve whitespace entities by setting theNewLineHandlingproperty of theXmlWriterSettingsclass toEntitize. However, within text nodes, this would only entitize\rto
, and not\nto
.The easiest solution is to derive from the
XmlWriterclass and override itsWriteStringmethod to manually replace the whitespace characters with their numeric character entities. TheWriteStringmethod also happens to be the place where .NET entitizes characters that are not permitted to appear in text nodes, such as the syntax markers&,<, and>, which are respectively entitized to&,<, and>.Since
XmlWriteris abstract, we shall derive fromXmlTextWriterin order to avoid having to implement all the abstract methods of the former class. Here is a quick-and-dirty implementation:If intended for use in a production environment, you’d want to do away with the
c.ToString()part, since it’s very inefficient. You can optimize the code by batching substrings of the originaltextthat do not contain any of the characters you want to entitize, and feeding them together into a singlebase.WriteStringcall.A word of warning: The following naive implementation will not work, since the base
WriteStringmethod would replace any&characters with&, thereby causing\rto be expanded to&#xA;.Finally, to save your
XDocumentinto a destination file or stream, just use the following snippet:Hope this helps!
Edit: For reference, here is an optimized version of the overridden
WriteStringmethod: