Omitting XML processing instruction when serializing an object
Asked Answered
C

6

10

I'm serializing an object in a C# VS2003 / .Net 1.1 application. I need it serialized without the processing instruction, however. The XmlSerializer class puts out something like this:

<?xml version="1.0" encoding="utf-16" ?> 
<MyObject>
    <Property1>Data</Property1>
    <Property2>More Data</Property2>
</MyObject>

Is there any way to get something like the following, without processing the resulting text to remove the tag?

<MyObject>
    <Property1>Data</Property1>
    <Property2>More Data</Property2>
</MyObject>

For those that are curious, my code looks like this...

XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
StringBuilder builder = new StringBuilder();

using ( TextWriter stringWriter = new StringWriter(builder) )
{
    serializer.Serialize(stringWriter, comments);
    return builder.ToString();
}
Cirque answered 2/10, 2008 at 21:1 Comment(0)
R
3

The following link will take you to a post where someone has a method of supressing the processing instruction by using an XmlWriter and getting into an 'Element' state rather than a 'Start' state. This causes the processing instruction to not be written.

Suppress Processing Instruction

If you pass an XmlWriter to the serializer, it will only emit a processing instruction if the XmlWriter's state is 'Start' (i.e., has not had anything written to it yet).

// Assume we have a type named 'MyType' and a variable of this type named 
'myObject' 
System.Text.StringBuilder output = new System.Text.StringBuilder(); 
System.IO.StringWriter internalWriter = new System.IO.StringWriter(output); 
System.Xml.XmlWriter writer = new System.Xml.XmlTextWriter(internalWriter); 
System.Xml.Serialization.XmlSerializer serializer = new 
System.Xml.Serialization.XmlSerializer(typeof(MyType)); 


writer.WriteStartElement("MyContainingElement"); 
serializer.Serialize(writer, myObject); 
writer.WriteEndElement(); 

In this case, the writer will be in a state of 'Element' (inside an element) so no processing instruction will be written. One you finish writing the XML, you can extract the text from the underlying stream and process it to your heart's content.

Rhythmics answered 2/10, 2008 at 21:6 Comment(2)
But this still requires post-processing the result to remove the MyContainingElement start and end tags, no? Although at least they will be known, so that's good...Orose
I played with this and replaced WriteStartElement with WriteRaw("") and got rid of the WriteEndElement - then all I needed to do to get good output was TrimStart() the BOM off. Cool!Orose
A
10

I made a small correction

XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
StringBuilder builder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
using ( XmlWriter stringWriter = XmlWriter.Create(builder, settings) )
{   
   serializer.Serialize(stringWriter, comments);  
  return builder.ToString();
}
Adaadabel answered 26/11, 2008 at 20:47 Comment(0)
P
7

In 2.0, you would use XmLWriterSettings.OmitXmlDeclaration, and serialize to an XmlWriter - however I don't think this exists in 1.1; so not entirely useful - but just one more "consider upgrading" thing... and yes, I realise it isn't always possible.

Plenteous answered 2/10, 2008 at 21:3 Comment(0)
R
3

The following link will take you to a post where someone has a method of supressing the processing instruction by using an XmlWriter and getting into an 'Element' state rather than a 'Start' state. This causes the processing instruction to not be written.

Suppress Processing Instruction

If you pass an XmlWriter to the serializer, it will only emit a processing instruction if the XmlWriter's state is 'Start' (i.e., has not had anything written to it yet).

// Assume we have a type named 'MyType' and a variable of this type named 
'myObject' 
System.Text.StringBuilder output = new System.Text.StringBuilder(); 
System.IO.StringWriter internalWriter = new System.IO.StringWriter(output); 
System.Xml.XmlWriter writer = new System.Xml.XmlTextWriter(internalWriter); 
System.Xml.Serialization.XmlSerializer serializer = new 
System.Xml.Serialization.XmlSerializer(typeof(MyType)); 


writer.WriteStartElement("MyContainingElement"); 
serializer.Serialize(writer, myObject); 
writer.WriteEndElement(); 

In this case, the writer will be in a state of 'Element' (inside an element) so no processing instruction will be written. One you finish writing the XML, you can extract the text from the underlying stream and process it to your heart's content.

Rhythmics answered 2/10, 2008 at 21:6 Comment(2)
But this still requires post-processing the result to remove the MyContainingElement start and end tags, no? Although at least they will be known, so that's good...Orose
I played with this and replaced WriteStartElement with WriteRaw("") and got rid of the WriteEndElement - then all I needed to do to get good output was TrimStart() the BOM off. Cool!Orose
P
1

What about omitting namespaces ?

instead of using

XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
                namespaces.Add("", "");

ex:

<message xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
Piscatelli answered 9/3, 2009 at 11:48 Comment(1)
#626427Piscatelli
I
0

If by "processing instruction" you mean the xml declaration, then you can avoid this by setting the OmitXmlDeclaration property of XmlWriterSettings. You'll need to serialize using an XmlWriter, to accomplish this.

XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
StringBuilder builder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;

using ( XmlWriter stringWriter = new StringWriter(builder, settings) )
{
    serializer.Serialize(stringWriter, comments);
    return builder.ToString();
}

But ah, this doesn't answer your question for 1.1. Well, for reference to others.

Interdental answered 2/10, 2008 at 21:5 Comment(0)
C
0

This works in .NET 1.1. (But you should still consider upgrading)

    XmlSerializer s1= new XmlSerializer(typeof(MyClass)); 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add( "", "" );


    MyClass c= new MyClass();
    c.PropertyFromDerivedClass= "Hallo";

    sw = new System.IO.StringWriter();
    s1.Serialize(new XTWND(sw), c, ns);
    ....

   /// XmlTextWriterFormattedNoDeclaration
   /// helper class : eliminates the XML Documentation at the
   /// start of a XML doc. 
   /// XTWFND = XmlTextWriterFormattedNoDeclaration
   public class XTWFND : System.Xml.XmlTextWriter
   {
     public XTWFND(System.IO.TextWriter w) : base(w) { Formatting = System.Xml.Formatting.Indented; }
     public override void WriteStartDocument() { }
   }
Casta answered 26/2, 2009 at 10:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.