I came up with some generic methods to do the job:
Public Shared Function DeserializeXMLToObject(ByVal input As String, ByVal type As System.Type) As Object Dim result As Object = Nothing Dim serializer As New XmlSerializer(type)
Try result = serializer.Deserialize(New XmlTextReader(New StringReader(input))) Catch ex As Exception Debug.WriteLine(ex.Message) End Try Return result
End Function
Public Shared Function SerializeObjectToXML(ByVal input As Object, ByVal type As System.Type) As String Dim returnXML As String = String.Empty Dim serializer As New XmlSerializer(type) Dim writer As New StringWriter
Try serializer.Serialize(New XmlTextWriter(writer), input) returnXML = writer.ToString()
Catch ex As Exception Debug.WriteLine(ex.Message) Finally writer.Close() End Try
Return returnXML
There are a few things to watch out for with the XmlSerilizer:
When the XmlSerilizer serializes the object it comes out looking something like this:
<?xml version="1.0" encoding="utf-16"?><Books xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Book> <Title>David McCarter's VB Tips & Techniques</Title> </Book></Books>
Where I work, we are saving our xml to hardware devices with limited memory. So the <?xml> element and "xmlns" attributes are taking up limited resources and have to be removed. You would think there would be a property in the XmlSerilizer to omit this extra stuff, but there isn't. So I had to roll my own. I changed the SerilizeObjectToXML call a little and added a new method called CleanXML.
Public Shared Function SerializeObjectToXML(ByVal input As Object, ByVal type As System.Type, ByVal clean As Boolean) As String Dim returnXML As String = String.Empty Dim serializer As New XmlSerializer(type) Dim writer As New StringWriter
If clean Then returnXML = CleanXML(returnXML) End If
End Function Private Shared Function CleanXML(ByVal input As String) As StringDim readerXML As New XmlTextReader(New StringReader(input))Dim writer As New StringWriterDim writerXML As New XmlTextWriter(writer)Dim returnXML As String = String.Empty
Try 'writerXML.WriteStartDocument() While readerXML.Read()
Select Case readerXML.NodeType Case XmlNodeType.Element writerXML.WriteStartElement(readerXML.Name) If (readerXML.HasAttributes) Then 'Cannot just use writer.WriteAttributes, 'else it will also emit xmlns attribute While readerXML.MoveToNextAttribute() If (readerXML.Name.CompareTo("xmlns") = -1) Then writerXML.WriteAttributeString(readerXML.Name, readerXML.Value) End If End While readerXML.MoveToElement() End If
If (readerXML.IsEmptyElement) Then writerXML.WriteEndElement() End If
Case XmlNodeType.Text writerXML.WriteString(readerXML.Value)
Case XmlNodeType.CDATA writerXML.WriteCData(readerXML.Value)
Case XmlNodeType.ProcessingInstruction writerXML.WriteProcessingInstruction(readerXML.Name, readerXML.Value)
Case XmlNodeType.Comment writerXML.WriteComment(readerXML.Value)
Case XmlNodeType.EntityReference writerXML.WriteEntityRef(readerXML.Name)
Case XmlNodeType.EndElement writerXML.WriteEndElement()
End Select End While
'writerXML.WriteEndDocument() writerXML.Flush() returnXML = writer.ToString()
Finally writerXML.Close() readerXML.Close() writer.Close() End Try
The readerXML.Name.CompareTo("xmlns") line in the method above will remove the "xmlns" attributes and the commented out WriteStartDocument and WriteEndDocument calls to the writer will remove the <?xml> element. Now your xml is bare!
But be careful when using this CleanXML, as I just found out, if your classes specify the xml namespace by using the XmlRoot or XmlType attributes, then deserializing won't work unless you put the "xmlns" attribute back in (that is my next task to do after I post this tip).
Here is the same code but for .NET 2.0 using generics:
Public Shared Function DeserializeXML(Of T)(ByVal xml As String) As T Dim serializer As New Serialization.XmlSerializer(GetType(T))
Return DirectCast(serializer.Deserialize(New XmlTextReader(New IO.StringReader(xml))), T)
Public Shared Function SerializeToXML(Of T)(ByVal obj As T) As String Dim returnXML As String = String.Empty Dim serializer As New Serialization.XmlSerializer(GetType(T))
Using writer As New IO.StringWriter serializer.Serialize(New XmlTextWriter(writer), obj) returnXML = writer.ToString() End Using
Tip Submitted By: David McCarter