How to Make the Xmlserializer Only Serialize Plain Xml

How can I make the xmlserializer only serialize plain xml?

To put this all together - this works perfectly for me:

// To Clean XML
public string SerializeToString<T>(T value)
{
var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var serializer = new XmlSerializer(value.GetType());
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;

using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, value, emptyNamespaces);
return stream.ToString();
}
}

How to serialize an c# object into xml without schema info?

You need a few xml tricks...

var serializer = new XmlSerializer(typeof(List<Ticket>));

var ns = new XmlSerializerNamespaces();
ns.Add("", "");
var sw = new StringWriter();
var xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings() { OmitXmlDeclaration = true });

serializer.Serialize(xmlWriter, model, ns);
string xml = sw.ToString();

Output:

<ArrayOfTicket>
<Ticket>
<CitationNumber>a</CitationNumber>
<Amount>1</Amount>
</Ticket>
<Ticket>
<CitationNumber>b</CitationNumber>
<Amount>2</Amount>
</Ticket>
</ArrayOfTicket>

PS: I added Indent = true to XmlWriterSettings to get the above output

How can I make XmlSerializer Deserialize tell me about typos on tag names

Having looked at Microsoft's published source code for XmlSerializer, it became apparent that there are events that you can subscribe to (which is what I was hoping for); but they aren't exposed on the XmlSerializer itself... you have to inject a struct containing them into the constructor.

So I've been able to modify the code from the question to have an event handler which gets called when an unknown node is encountered (which is exactly what I was after). You need one extra using, over the ones given in the question...

using System.Xml;

and then here is the modified "Load" method...

    private static Example Load(string serialized)
{
XmlDeserializationEvents events = new XmlDeserializationEvents();
events.OnUnknownNode = (sender, e) => System.Diagnostics.Debug.WriteLine("Unknown Node: " + e.Name);

var xmlSerializer = new XmlSerializer(typeof(Example));
using var reader = XmlReader.Create(new StringReader(serialized));
return (Example)xmlSerializer.Deserialize(reader, events);
}

So now I just need to do something more valuable than just write a line to the Debug output.

Note that more events are available, as described on the XmlDeserializationEvents page, and I'll probably pay attention to each of them.

How to serialize a class instance to XML in .NET Core?

If I understood you correctly, you just want to export plain xml.

Then you need to set XmlWriterSettings as below and tell the serializer to use a empty namespace.

var emptyNamespaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
var settings = new XmlWriterSettings()
{
OmitXmlDeclaration = true,
};

using (var stream = new StringWriter())
using (var writer = XmlWriter.Create(stream, settings))
{
var serializer = new XmlSerializer(orders.GetType());
serializer.Serialize(writer, orders, emptyNamespaces);
string xml = stream.ToString();
}

Also see How can I make the xmlserializer only serialize plain xml?.

Can I Serialize XML straight to a string instead of a Stream with C#?

Fun with extension methods...

var ret = john.ToXmlString()

public static class XmlTools
{
public static string ToXmlString<T>(this T input)
{
using (var writer = new StringWriter())
{
input.ToXml(writer);
return writer.ToString();
}
}
public static void ToXml<T>(this T objectToSerialize, Stream stream)
{
new XmlSerializer(typeof(T)).Serialize(stream, objectToSerialize);
}

public static void ToXml<T>(this T objectToSerialize, StringWriter writer)
{
new XmlSerializer(typeof(T)).Serialize(writer, objectToSerialize);
}
}

Attempting to serialize a class without a namespace or declaration

  1. The XmlWriter does not implement IDisposable, i.e., it has no Dispose method that the Using statement could call. Simply fix it by not using the Using-statement.

    Dim writer = XmlWriter.Create(stream, settings)
  2. The second parameter must be the object that you want to serialize, i.e., probably dataItem in this case.

    serializer.Serialize(writer, dataItem)

As for removing the namespaces and the comment, here is a solution:

Sub Test()
Dim dataItem = New DataClass With {.Id = 5, .Name = "Test"}

' Serialize.
Dim serializer As New XmlSerializer(GetType(DataClass))
Dim sb As New StringBuilder()
Using writer As New StringWriter(sb)
serializer.Serialize(writer, dataItem)
End Using

Dim xml = RemoveNamespaces(sb.ToString())

Console.WriteLine(xml)
End Sub

Private Function RemoveNamespaces(ByVal xml As String) As String
Dim doc = New XmlDocument()
doc.LoadXml(xml)

' This assumes that we have only a namespace attribute on the root element.
doc.DocumentElement.Attributes.RemoveAll()

Dim settings As New XmlWriterSettings With {.Indent = True, .OmitXmlDeclaration = True}
Dim sb As New StringBuilder()
Using stringWriter As New StringWriter(sb)
Using writer = XmlWriter.Create(stringWriter, settings)
doc.WriteTo(writer)
End Using
End Using
Return sb.ToString()
End Function

It is using this test class

Public Class DataClass
Public Property Id As Integer
Public Property Name As String
End Class

Serialize to XML removing namespaces, xml definition and so on

The xmlns:i XML Namespace is automatically emitted by .NET's DataContractSerializer and doesn't provide an option to omit it.

Only real way to remove it is to serialize to XML and then strip the attributes from the raw XML, e.g something like:

var xml = dto.ToXml()
.Replace(" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"","");
return xml;

If you have more complicated requirements you can also look at loading and removing XML with XDocument.



Related Topics



Leave a reply



Submit