我还没有找到使用.NET的XmlWriter和相关的XmlWriterSettings以与Visual Studio自动格式化命令(Ctrl-E Ctrl-D,或者根据键盘映射,Ctrl-K Ctrl-D)完全相同的缩进形式格式化XML字符串的方法。
我想这样做是因为我习惯在VS中自动格式化所有文件,包括代码和.config文件。我有一个安装程序应用程序,可以更新.config文件,并且我想看到实际的差异,而不是整个文档被更改。
我还没有探索所有自动格式化的不同选项,但我喜欢每个XML属性都在单独的一行上,第一个属性与开放标签在同一行上,后续属性与第一个属性对齐,就像这样:
<asset assetId="12345"
bucket="default"
owner="nobody">
<file path="\\localhost\share\assetA.mov"/>
<metadata metadataId="23456"
key="asset_type"
value="video"/>
</asset>
我尝试使用XmlWriterSettings属性“NewLineHandling = NewLineHandling.None”和“NewLineOnAttributes = true”进行格式化,但这会将第一个属性放在开标签下方,并且所有属性的缩进都相同,无论元素名称中有多少个字符,就像这样:
<asset
assetId="12345"
bucket="default"
owner="nobody">
<file
path="\\localhost\share\assetA.mov" />
<metadata metadataId="23456"
key="asset_type"
value="video" />
</asset>
注意标准的XmlWriter也会在仅具有属性的元素后加上" />"(斜杠前多一个空格),这是我不喜欢的,但我不确定是否符合XML标准。我认为Visual Studio应该使用相同的API选项供开发人员方便使用,但是我还没有找到那些神奇的设置。无论如何,下面是我的格式化方法:
public static string FormatXml( string xmlString, bool indented )
{
using ( TextReader textReader = new StringReader( xmlString ) )
using ( XmlReader xmlReader = new XmlTextReader( textReader ) )
{
using ( TextWriter textWriter = new StringWriter() )
{
var settings = new XmlWriterSettings();
if ( indented )
{
settings.Indent = true;
settings.IndentChars = " ";
settings.NewLineOnAttributes = true;
settings.NewLineHandling = NewLineHandling.None;
}
using ( var xmlWriter = XmlWriter.Create( textWriter, settings ) )
{
while ( xmlReader.Read() )
xmlWriter.WriteNode( xmlReader, false );
}
return textWriter.ToString();
}
}
}