I have the following object:
public class MyClass
{
public int Id { get; set;}
public string Name { get; set; }
}
I'm wanting to serialize this to the following xml string:
<MyClass>
<Id>1</Id>
<Name>My Name</Name>
</MyClass>
Unfortunately, when I use the XMLSerializer I get a string which looks like:
<?xml version="1.0" encoding="utf-8"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Id>1</Id>
<Name>My Name</Name>
</MyClass>
I'm not wanting MyClass to be the root element the document, rather I'm eventually wanting to add the string with other similar serialized objects which will be withi开发者_JS百科n a larger xml document.
i.e. Eventually I'll have a xml string which looks like this:
<Classes>
<MyClass>
<Id>1</Id>
<Name>My Name</Name>
</MyClass>
<MyClass>
<Id>1</Id>
<Name>My Name</Name>
</MyClass>
</Classes>"
My first thought was to create a class as follows:
public class Classes
{
public List<MyClass> MyClasses { get; set; }
}
...but that just addes an additional node called MyClasses to wrap the list of MyClass....
My gut feeling is that I'm approaching this the wrong way and that my lack of experience with creating xml files isn't helping to point me to some part of the .NET framework or some other library that simplifies this.
You need to use the XmlWriter object - this gives you full control over how the XML will be rendered. You also need to pass a XmlSerializerNamespaces instance to the serializer to get what you need.
The sample program below achieves exactly what you are looking for (notice how the XmlWriter is initialized with XmlWriterSettings, and how the XmlNamespaces instance is passed to the serializer):
public class MyClass { public int Id { get; set; } public string Name { get; set; } }
class Program { static void Main(string[] args) { var xml = new StringBuilder(); using (var writer = XmlWriter.Create(xml, new XmlWriterSettings { Indent = true, ConformanceLevel = ConformanceLevel.Auto, OmitXmlDeclaration = true })) { MyClass myClass = new MyClass { Id = 1, Name = "My Name" }; var ns = new XmlSerializerNamespaces(); ns.Add("", ""); var xs = new XmlSerializer(typeof(MyClass), ""); xs.Serialize(writer, myClass, ns); } Console.WriteLine(xml.ToString()); // pause program execution to review results... Console.WriteLine("Press enter to exit"); Console.ReadLine(); }
//Result:
<MyClass>
<Id>1</Id>
<Name>My Name</Name>
</MyClass>
Don't use the XmlSerializer, but use DataContracts instead. Create a new type Classes
, that inherits List<MyClass>
like:
[CollectionDataContract(Name = "Classes")]
public class Classes : List<MyClass>
{
}
[DataContract(Name = "MyClass")]
public class MyClass
{
[DataMember(Name="Id")]
public int Id { get;set; }
}
Now use the DataContractSerializer
to serialize your Classes
instance:
Classes myItems = new Classes();
myItems.Add( ... );
DataContractSerializer serializer = new DataContractSerializer(typeof(Classes));
serializer.WriteObject( /* some stream */, myItems);
in response to comment
Use something like this:
[CollectionDataContract(Name = "MyClasses1")]
public class MyClassesOne : List<MyClass> { }
[CollectionDataContract(Name = "MyClasses2")]
public class MyClassesTwo : List<MyClass> { }
[DataContract(Name = "Classes")]
public class Classes {
[DataMember] public MyClassesOne MyClasses1 { get; set; }
[DataMember] public MyClassesTwo MyClasses2 { get; set; }
}
It's way more easy to consume by any client.
It shouldn't be a problem for the element to be the root node. You can import it (it'll be the XmlDocument's DocumentElement) into another XmlDocument later on.
You could take a look at XStream for .NET. This tutorial shows you how to achieve what you want.
精彩评论