代码之家  ›  专栏  ›  技术社区  ›  Andrew Bennet

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

  •  0
  • Andrew Bennet  · 技术社区  · 7 年前

    我有一个XML文档,我想用规范化的缩进(使用两个空格)序列化它,但是保留元素之间的任何额外换行符。我在用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文档,以便缩进是正确的,但我不想删除用户添加的换行符以提高可读性。

    0 回复  |  直到 7 年前
        1
  •  0
  •   Andrew Bennet    7 年前

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

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

    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);
        }
    }
    
    推荐文章