如何使用XmlSerializer在不同级别指定XmlElement?

时间:2012-09-04 15:10:56

标签: c# xmlserializer

我有一个我要序列化为xml的类。我想在生成的xml(元素中的元素)中将其中一个属性向下移动一级,而不更改类的结构。是否可以使用XmlSerializer执行此操作?

一个例子:

生成的xml:

<Person>
    <firstname xmlns=\"http://myschema.com\">John</firstname>
    <postcode xmlns=\"http://myschema.com\">N1 0XE</postcode>
</Person>

所需的xml:

<Person>
    <firstname xmlns=\"http://myschema.com\">John</firstname>
    <address>
        <postcode xmlns=\"http://myschema.com\">N1 0XE</postcode>
    </address>
</Person>

代码:

[Serializable]
[XmlType(Namespace = "http://myschema.com")]
public class Person
{
    [XmlElement("firstname")]
    public string FirstName { get; set; }

    [XmlElement("postcode")]
    public string Postcode { get; set; }
}

串行:

var xmlSerializer = new XmlSerializer(typeof(Person));
var stringWriter = new StringWriter();
var xmlWriter = XmlWriter.Create(stringWriter);

xmlSerializer.Serialize(xmlWriter, person);

2 个答案:

答案 0 :(得分:3)

我知道更改生成的标准输出xml的唯一方法是实现IXmlSerializable。因此,您不必更改公共结构,但必须为某些方法提供实现。

public class Person : IXmlSerializable
{
    [XmlElement("firstname")]
    public string FirstName { get; set; }

    [XmlElement("postcode")]
    public string Postcode { get; set; }

    #region IXmlSerializable Member

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        if (reader.Read())
        {
            FirstName = reader.ReadInnerXml();
        }

        reader.Read(); 

        Postcode = reader.ReadInnerXml();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteElementString("firstname ", FirstName);
        writer.WriteStartElement("address");
        writer.WriteElementString("postcode", Postcode);
        writer.WriteEndElement();
    }

    #endregion

    // for demo purposes only !
    public override string ToString()
    {
        return FirstName + ", " + Postcode;
    }

    // source to test the exported file and read it right after!
    Person p = new Person() { FirstName = "jon doe", Postcode = "N1 OX" };

    XmlSerializer xs = new XmlSerializer(typeof(Person));
    StreamWriter sw = new StreamWriter("export.xml");
    xs.Serialize(sw, p);
    sw.Close();

    StreamReader sr = new StreamReader("export.xml");
    Person p1 = xs.Deserialize(sr) as Person;
    Debug.WriteLine(p1.ToString());

@XmlSubElement - 只有一堆attributes available for xmlSerialization。不幸的是,没有 subElement 或任何类似的东西。

答案 1 :(得分:1)

还有另外两种方法可以不需要对您的类进行任何更改(甚至不实现IXmlSerializable):

  1. 一个自定义的XmlWriter,它会在编写元素时将<address>包装起来;
  2. 使用合适的XSL转换后处理XmlSerializer的输出。