When looking at a ".csproj" file, a developer's first reaction is "cool, it's XML, I can read and write it". It may be missing the "<?xml ... ?>" processing instruction, but who cares - you can Load() it into a System.Xml.XmlDocument, so everything's fine.
As long as you intend to only read from the ".csproj" file, that's the end of the story. But if you actually want to write to a ".csproj" file (not such a good idea anyway), be prepared for an unpleasant surprise. If you Save() the XmlDocument to a file, and one of the of the gazillion attributes contains a quote, the saved project file is virtually worthless.
An example: Say you put echo "Hello World!" into your post build step. If you load the resulting project file into an XmlDocument and save it back to a file, you'll get something like this:
... PostBuildEvent="echo "Hello World!"" ...
Looks ok, right? Not to VS.Net. Because VS.Net expects this:
... PostBuildEvent = 'echo "Hello World!"' ...
So when you load the project file back into VS.Net, the next time the post build step is performed, VS.Net tries to execute "echo "Hello World"", which of course fails with a lot of noise (remember that "&" has a special meaning on the command line). XmlDocument is smart enough to read and understand the original ".csproj" file (the single quotes are valid XML after all), but when saving to a file, it uses double quotes to surround the attribute value and escapes quote characters inside the value if necessary.
The fact that VS.Net is not able to read the file makes me wonder what kind of XML parser is used inside VS.Net - did somebody have the stupid idea to write one from scratch?
Before somebody tells me that I'm not supposed to manipulate the ".csproj" file, here's a way to make VS.Net look stupid without any external help:
Put echo "Hello 'World'!" into the post build step. VS.Net writes the following into the project file:
... PostBuildEvent = "echo "Hello 'World'!"" ...
Oops... attribute value surrounded by double quotes, escaped quotes inside... that means trouble. If you build the project immediately after setting the post build step, "Hello 'World'!" appears in the build output as expected. But if you (re)load the project, BLAM! "Post-Build Event failed".