在字符串属性的XML序列化缩进文字? [英] Indent text in xml serialization of string property?

查看:352
本文介绍了在字符串属性的XML序列化缩进文字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字符串属性,它包含文本换行。本文部分在空格HTML文本的属性被忽略。

I have a string property which will contain text with newlines. This text has some of the properties of HTML text in that whitespace is disregarded.

如果我使用XML序列化序列化此类型,换行正确序列化,但缺口是错误的。我想序列化过程缩进的行,以保持XML的格式,因为这些空白字符以后不会被忽略。

If I serialize this type using XML serialization, the newlines are serialized properly, but the indentation is "wrong". I want the serialization process to indent the lines to keep the formatting of the XML, since those whitespace characters will be disregarded later anyway.

下面是一个例子 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>

所需的输出:

Desired output:

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

这可能吗?如果是这样,怎么样?我宁愿不这样做只是增加了空格在自己的hackish的方式。

Is this possible? If so, how? I'd rather not do the hackish way of just adding the whitespace in myself.

这样做的原因是,这XML将被查看和人编辑,所以我想为初始输出得到更好的格式化为他们开箱

The reason for this is that this XML will be viewed and edited by people, so I'd like for the initial output to be better formatted for them out of the box.

推荐答案

我碰到了同样的问题。最后我想出了一个自定义的作家:

I bumped into the same issue. At the end I came out with a custom writer:

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>

这篇关于在字符串属性的XML序列化缩进文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆