gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 12:10:18 28 4
gpt4 key购买 nike

我有一个字符串属性,它将包含带有换行符的文本。此文本具有 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;
}
}

实际输出:

<?xml version="1.0" encoding="utf-16"?>
<dummy>
<text>Line 1
Line 2
Line 3</text>
</dummy>

期望的输出:

<?xml version="1.0" encoding="utf-16"?>
<dummy>
<text>
Line 1
Line 2
Line 3
</text>
</dummy>

这可能吗?如果是这样,如何?我宁愿不采用仅在自己中添加空格的骇人听闻的方式。

这样做的原因是这个 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());
}

输出:

<?xml version="1.0" encoding="utf-16"?>
<root>
<child>
<elementIndented>
Line 1
Line 2
Line 3
</elementIndented>
<elementPreserved xml:space="preserve"> Line 1
Line 2
Line 3 </elementPreserved>
</child>
</root>

关于c# - 在字符串属性的 xml 序列化中缩进文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18810954/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com