If you need to be able to serialize to match an external schema, then you obviously shouldn't be using the DataContractSerializer. That's not what it's for.
You can either use the XmlSerializer, which is intended to give you more control over the serialized XML, or implement IXmlSerializable, and gain complete control over the XML, or you can write your own custom serialization using LINQ to XML. This will let you do exactly what you mention - serialize the same data in different ways. Example:
Data
internal class Person
{
internal string Name { get; set; }
internal string Telephone { get; set; }
internal Address HomeAddress { get; set; }
internal Address WorkAddress { get; set; }
}
internal class Address
{
internal string Line1 { get; set; }
internal string Line2 { get; set; }
internal string City { get; set; }
internal string State { get; set; }
internal string PostalCode { get; set; }
}
Test Program
private static void Main()
{
var person = new Person
{
Name = "John Saunders",
Telephone = "something",
HomeAddress = new Address
{
Line1 = "Line 1",
Line2 = "Line 2",
City = "SomeCity",
State = "SS",
PostalCode = "99999-9999",
},
WorkAddress = new Address
{
Line1 = "Line 1a",
Line2 = "Line 2a",
City = "SomeCitay",
State = "Sa",
PostalCode = "99999-999a",
},
};
XDocument personWithElements = SerializeAsElements(person);
personWithElements.Save("PersonWithElements.xml");
XDocument personWithAttributes = SerializeAsAttributes(person);
personWithAttributes.Save("PersonWithAttributes.xml");
}
Serialization as Elements:
private static XDocument SerializeAsElements(Person person)
{
return new XDocument(
new XElement("Person",
new XElement("Name", person.Name),
new XElement("Telephone", person.Telephone),
SerializeAddressAsElements(person.HomeAddress, "HomeAddress"),
SerializeAddressAsElements(person.WorkAddress, "WorkAddress"))
);
}
private static XElement SerializeAddressAsElements(Address address, string elementName)
{
return new XElement(elementName,
new XElement("Line1", address.Line1),
new XElement("Line2", address.Line2),
new XElement("City", address.City),
new XElement("State", address.State),
new XElement("PostalCode", address.PostalCode)
);
}
Serialization as Attributes:
private static XDocument SerializeAsAttributes(Person person)
{
return new XDocument(
new XElement("Person",
new XAttribute("Name", person.Name),
new XAttribute("Telephone", person.Telephone),
SerializeAddressAsAttributes(person.HomeAddress, "HomeAddress"),
SerializeAddressAsAttributes(person.WorkAddress, "WorkAddress"))
);
}
private static XElement SerializeAddressAsAttributes(Address address, string elementName)
{
return new XElement(elementName,
new XAttribute("Line1", address.Line1),
new XAttribute("Line2", address.Line2),
new XAttribute("City", address.City),
new XAttribute("State", address.State),
new XAttribute("PostalCode", address.PostalCode)
);
}
PersonWithElements:
<?xml version="1.0" encoding="utf-8"?>
<Person>
<Name>John Saunders</Name>
<Telephone>somethine</Telephone>
<HomeAddress>
<Line1>Line 1</Line1>
<Line2>Line 2</Line2>
<City>SomeCity</City>
<State>SS</State>
<PostalCode>99999-9999</PostalCode>
</HomeAddress>
<WorkAddress>
<Line1>Line 1a</Line1>
<Line2>Line 2a</Line2>
<City>SomeCitay</City>
<State>Sa</State>
<PostalCode>99999-999a</PostalCode>
</WorkAddress>
</Person>
PersonWithAttributes:
<?xml version="1.0" encoding="utf-8"?>
<Person Name="John Saunders" Telephone="somethine">
<HomeAddress Line1="Line 1" Line2="Line 2" City="SomeCity" State="SS" PostalCode="99999-9999" />
<WorkAddress Line1="Line 1a" Line2="Line 2a" City="SomeCitay" State="Sa" PostalCode="99999-999a" />
</Person>