在字符串属性的xml序列化中缩进文本?

我有一个字符串属性,其中包含带换行符的文本。 此文本具有HTML文本的一些属性,因为空格被忽略。

如果我使用XML序列化序列化此类型,则新行被正确序列化,但缩进是“错误的”。 我希望序列化过程缩进行以保持XML的格式,因为无论如何这些空白字符将被忽略。

这是LINQPad程序的示例:

void Main() { var d = new Dummy(); d.Text = @"Line 1 Line 2 Line 3"; var serializer = new XmlSerializer(typeof(Dummy)); var ns = new XmlSerializerNamespaces(); ns.Add("", ""); using (var writer = new StringWriter()) { serializer.Serialize(writer, d, ns); writer.ToString().Dump(); } } [XmlType("dummy")] public class Dummy { [XmlElement("text")] public string Text { get; set; } } 

实际产量:

   Line 1 Line 2 Line 3  

期望的输出:

    Line 1 Line 2 Line 3   

这可能吗? 如果是这样,怎么样? 我宁愿不做我自己添加空白的hackish方式。

这样做的原因是这个XML将由人们查看和编辑,所以我希望初始输出能够更好地为他们开箱即用。

我碰到了同样的问题。 最后,我找到了一位自定义作家:

 public class IndentTextXmlWriter : XmlTextWriter { private int indentLevel; private bool isInsideAttribute; public IndentTextXmlWriter(TextWriter textWriter): base(textWriter) { } public bool IndentText { get; set; } public override void WriteStartAttribute(string prefix, string localName, string ns) { isInsideAttribute = true; base.WriteStartAttribute(prefix, localName, ns); } public override void WriteEndAttribute() { isInsideAttribute = false; base.WriteEndAttribute(); } public override void WriteStartElement(string prefix, string localName, string ns) { indentLevel++; base.WriteStartElement(prefix, localName, ns); } public override void WriteEndElement() { indentLevel--; base.WriteEndElement(); } public override void WriteString(string text) { if (String.IsNullOrEmpty(text) || isInsideAttribute || Formatting != Formatting.Indented || !IndentText || XmlSpace == XmlSpace.Preserve) { base.WriteString(text); return; } string[] lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); string indent = new string(IndentChar, indentLevel * Indentation); foreach (string line in lines) { WriteRaw(Environment.NewLine); WriteRaw(indent); WriteRaw(line.Trim()); } WriteRaw(Environment.NewLine); WriteRaw(new string(IndentChar, (indentLevel - 1) * Indentation)); } } 

你可以像这样使用它:

 [TestMethod] public void WriteIndentedText() { var result = new StringBuilder(); using (var writer = new IndentTextXmlWriter(new StringWriter(result)){Formatting = Formatting.Indented, IndentText = true}) { string text = @" Line 1 Line 2 Line 3 "; // some root writer.WriteStartDocument(); writer.WriteStartElement("root"); writer.WriteStartElement("child"); // test auto-indenting writer.WriteStartElement("elementIndented"); writer.WriteString(text); writer.WriteEndElement(); // test space preserving writer.WriteStartElement("elementPreserved"); writer.WriteAttributeString("xml", "space", null, "preserve"); writer.WriteString(text); writer.WriteEndDocument(); } Debug.WriteLine(result.ToString()); } 

并输出:

     Line 1 Line 2 Line 3   Line 1 Line 2 Line 3