我有一个XML文档,我想用规范化的缩进(使用两个空格)序列化,但保留Elements之间的任何其他换行符。我正在使用C#。最好是我会规范化换行符(所以它们都是\r\n
),但至关重要的是我想保持多个连续的换行符。
例如,给定输入文档:
<root>
<elementOne>Hello</elementOne>
<elementTwo>I am misaligned</elementTwo>
<elementThree>I am indented with a Tab character</elementThree>
<!-- Here is a comment preceeding another element -->
<elementFour />
</root>
我想生成输出文档:
<root>
<elementOne>Hello</elementOne>
<elementTwo>I am slightly misaligned</elementTwo>
<elementThree>I am indented with a Tab character</elementThree>
<!-- Here is a comment preceeding another element -->
<elementFour />
</root>
如果我将输入文档解析为XElement
然后序列化,我会得到带有规范化间距的输出,但删除了额外的换行符:
<root>
<elementOne>Hello</elementOne>
<elementTwo>I am slightly misaligned</elementTwo>
<elementThree>I am indented with a Tab character</elementThree>
<!-- Here is a comment preceeding another element -->
<elementFour />
</root>
我尝试使用XDocument.Load
和LoadOptions.PreserveWhitespace
,但后来我找不到一种方法来缩进标准化。我也尝试过如下使用XmlWriterSettings
:
XmlWriterSettings settings = new XmlWriterSettings {
Indent = true,
IndentChars = " ",
NewLineChars = "\r\n",
NewLineHandling = NewLineHandling.None
};
但调整这些设置似乎要么规范化换行符和缩进,要么两者都没有。
我想要这种行为的原因是我想“漂亮地打印”一个大的用户可编辑的XML文档,以便缩进是正确的,但我不想删除用户为了可读性而添加的换行符。
不可能只保留元素之间的空白部分:空白被认为是重要的,或者不是。
另一种解决方案是使用占位符注释替换所有空行,以常规方式格式化文档,然后删除注释(但保留空行)。
例如:
public static class XmlFormatting {
static readonly string sNewLineComment = new XComment($"x-newline-placeholder-{Guid.NewGuid()}").ToString();
static readonly Regex sNewLineCommentRegex = new Regex($@"^\s*{sNewLineComment}\s*$", RegexOptions.Compiled | RegexOptions.Multiline);
static readonly Regex sEmptyLineRegex = new Regex(@"^\s*$", RegexOptions.Compiled | RegexOptions.Multiline);
public static string PrettyPrintXml(string inputXml) {
string newlinesReplacedWithComments = sEmptyLineRegex.Replace(inputXml, sNewLineComment);
string formattedDocument = XDocument.Parse(newlinesReplacedWithComments, LoadOptions.None).ToString();
return sNewLineCommentRegex.Replace(formattedDocument, string.Empty);
}
}