Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET XML Serialization without <?xml> text declaration

Tags:

I'm trying to generate XML like this:

<?xml version="1.0"?>
<!DOCTYPE APIRequest SYSTEM
"https://url">
<APIRequest>
  <Head>
      <Key>123</Key>
  </Head>
  <ObjectClass>
    <Field>Value</Field
  </ObjectClass>
</APIRequest>

I have a class (ObjectClass) decorated with XMLSerialization attributes like this:

[XmlRoot("ObjectClass")]
public class ObjectClass
{
    [XmlElement("Field")]
    public string Field { get; set; }
}

And my really hacky intuitive thought to just get this working is to do this when I serialize:

ObjectClass inst = new ObjectClass();
XmlSerializer serializer = new XmlSerializer(inst.GetType(), "");

StringWriter w = new StringWriter();
w.WriteLine(@"<?xml version=""1.0""?>");
w.WriteLine("<!DOCTYPE APIRequest SYSTEM");
w.WriteLine(@"""https://url"">");
w.WriteLine("<APIRequest>");
w.WriteLine("<Head>");
w.WriteLine(@"<Field>Value</Field>");
w.WriteLine(@"</Head>");

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); 
serializer.Serialize(w, inst, ns);

w.WriteLine("</APIRequest>");

However, this generates XML like this:

<?xml version="1.0"?>
<!DOCTYPE APIRequest SYSTEM
"https://url">
<APIRequest>
  <Head>
      <Key>123</Key>
  </Head>
  <?xml version="1.0" encoding="utf-16"?>
  <ObjectClass>
    <Field>Value</Field>
  </ObjectClass>
</APIRequest>

i.e. the serialize statement is automatically adding a <?xml text declaration.

I know I'm attacking this wrong so can someone point me in the right direction?

As a note, I don't think it will make practical sense to just make an APIRequest class with an ObjectClass in it (because there are say 20 different types of ObjectClass that each needs this boilerplate around them) but correct me if I'm wrong.

like image 421
Matt Mitchell Avatar asked Jun 01 '09 05:06

Matt Mitchell


People also ask

What is the correct way of using XML serialization?

As with the CreatePo method, you must first construct an XmlSerializer, passing the type of class to be deserialized to the constructor. Also, a FileStream is required to read the XML document. To deserialize the objects, call the Deserialize method with the FileStream as an argument.

Which annotation is needed for serialization and deserialization of XML format?

Jackson annotations are useful in defining and controlling the process of serialization and deserialization across various formats such as XML, JSON, and YAML.

What is the basic difference between SOAP serialization and XML serialization?

- SoapFormatter is better to serialize arbitrary data. - XML Serialization would just serialize the public properties of an object. - The XML Serializer is used typically for serializing simple types across web services. - Xmlserializer is better, more flexible and faster.

What occasions the XML serialization throws an exception?

XmlSerializer throws exception when the type belongs to an assembly with no location property set #24614.


2 Answers

try this:

internal static string ToXml(object obj)
{
  string retval = null;
  if (obj != null)
  {
    StringBuilder sb = new StringBuilder();
    using(XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = true }))
    {
      new XmlSerializer(obj.GetType()).Serialize(writer, obj);
    }
    retval = sb.ToString();
  }
  return retval;
}
like image 61
Giuseppe Dimauro Avatar answered Sep 19 '22 15:09

Giuseppe Dimauro


Never build xml using string concatenation. It's evil.

Output:

<?xml version="1.0" encoding="utf-16"?>
<!DOCTYPE APIRequest SYSTEM "https://url">
<APIRequest>
  <Head>
    <Key>123</Key>
  </Head>
  <ObjectClass>
    <Field>Value</Field>
  </ObjectClass>
</APIRequest>

Code:

using System;
using System.Diagnostics;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

public static class Program {
    public static void Main() {
        var obj = new ObjectClass { Field = "Value" };

        var settings = new XmlWriterSettings {
            Indent = true
        };

        var xml = new StringBuilder();
        using (var writer = XmlWriter.Create(xml, settings)) {
            Debug.Assert(writer != null);

            writer.WriteDocType("APIRequest", null, "https://url", null);
            writer.WriteStartElement("APIRequest");
            writer.WriteStartElement("Head");
            writer.WriteElementString("Key", "123");
            writer.WriteEndElement(); // </Head>

            var nsSerializer = new XmlSerializerNamespaces();
            nsSerializer.Add("", "");

            var xmlSerializer = new XmlSerializer(obj.GetType(), "");
            xmlSerializer.Serialize(writer, obj, nsSerializer);

            writer.WriteEndElement(); // </APIRequest>
        }

        Console.WriteLine(xml.ToString());
        Console.ReadLine();
    }
}

[XmlRoot("ObjectClass")]
public class ObjectClass {
    [XmlElement("Field")]
    public string Field { get; set; }
}
like image 43
sisve Avatar answered Sep 19 '22 15:09

sisve