在C#中序列化/读取XML时如何规范化缩进而不是换行符

问题描述 投票:0回答:1

我有一个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.LoadLoadOptions.PreserveWhitespace,但后来我找不到一种方法来缩进标准化。我也尝试过如下使用XmlWriterSettings

XmlWriterSettings settings = new XmlWriterSettings {
    Indent = true,
    IndentChars = "  ",
    NewLineChars = "\r\n",
    NewLineHandling = NewLineHandling.None
};

但调整这些设置似乎要么规范化换行符和缩进,要么两者都没有。

我想要这种行为的原因是我想“漂亮地打印”一个大的用户可编辑的XML文档,以便缩进是正确的,但我不想删除用户为了可读性而添加的换行符。

c# .net xml line-breaks code-formatting
1个回答
0
投票

不可能只保留元素之间的空白部分:空白被认为是重要的,或者不是。

另一种解决方案是使用占位符注释替换所有空行,以常规方式格式化文档,然后删除注释(但保留空行)。

例如:

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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.