.net 具有并排元素的C# XML序列化

s3fp2yjn  于 2022-12-27  发布在  .NET
关注(0)|答案(1)|浏览(131)

我目前正在尝试理解用C#将对象序列化为XML的概念。我已经到了一切都工作正常的地步,但现在我的任务是以这样一种方式格式化XML输出文件,其中元素是并排的,而不是一个在另一个下面。例如:

这就是它应该有的样子

<House>
  <Address>
    <Street>Some Street</Street><HouseNo>123</HouseNo><State>Texas</State>
  </Address>
<House>

但我只能做到这样

<House>
  <Address>
    <Street>Some Street</Street>
    <HouseNo>123</HouseNo>
    <State>Texas</State>
  </Address>
</House>

有什么方法可以像我在第一个例子中描述的那样格式化输出吗?任何帮助都将不胜感激。
我已经尝试更改一些XmlWriterSettings,如IndentNewLineHandling,但到目前为止还没有成功。我还尝试阅读XmlSerializer代码,以尝试了解发生了什么或在哪里进行更改以获得我想要的结果,但似乎并不顺利。

nle07wnf

nle07wnf1#

您可以创建一个带有自定义序列化的地址类,这是一个full working example

using System;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.Serialization;
                    
public class Program
{
    public static void Main()
    {
        var houseBefore = new House
        {
            Address = new FlatAddress
                              {
                                 Street = "SomeStreet",
                                 HouseNo = "123",
                                 State = "Texas"
                              }
        };
        
        var serializer = new XmlSerializer(typeof(House));
        string xml;
        using (var writer = new StringWriter())
        {
            serializer.Serialize(writer, houseBefore);
            xml = writer.ToString();
        }
        
        Console.WriteLine(xml);
        
        House houseAfter;
        using (var reader = new StringReader(xml))
        {
            houseAfter = serializer.Deserialize(reader) as House;
        }
        
        Debug.Assert(houseBefore.Address.Street == houseAfter.Address.Street);
        Debug.Assert(houseBefore.Address.HouseNo == houseAfter.Address.HouseNo);
        Debug.Assert(houseBefore.Address.State == houseAfter.Address.State);
    }
}

public sealed class House
{
    public FlatAddress Address { get; set; }
}

public sealed class FlatAddress : IXmlSerializable
{
    public string Street { set; get; }
    public string HouseNo { set; get; }
    public string State { set; get; }
    
    public XmlSchema GetSchema()
    {
        return default;
    }
    
    public void ReadXml(XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                    case nameof(Street):
                        this.Street = reader.ReadElementContentAsString();
                        break;

                    case nameof(HouseNo):
                        this.HouseNo = reader.ReadElementContentAsString();
                        break;

                    case nameof(State):
                        this.State = reader.ReadElementContentAsString();
                        break;
                }
            }
        }
    }
    
    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString(nameof(Street), this.Street);
        var houseNoXml = new XElement(nameof(HouseNo), this.HouseNo);
        writer.WriteRaw(houseNoXml.ToString());
        var stateXml = new XElement(nameof(State), this.State);
        writer.WriteRaw(stateXml.ToString());
        
        if (writer.Settings.NewLineHandling == NewLineHandling.Replace)
        {
            writer.WriteRaw(writer.Settings.NewLineChars);
        }
        
        if (writer.Settings.Indent)
        {
            writer.WriteRaw(writer.Settings.IndentChars);
        }
    }
}

相关问题