4

Given this generic serialization code:

public virtual string Serialize(System.Text.Encoding encoding)
{
 System.IO.StreamReader streamReader = null;
 System.IO.MemoryStream memoryStream = null;

 memoryStream = new System.IO.MemoryStream();
 System.Xml.XmlWriterSettings xmlWriterSettings = new System.Xml.XmlWriterSettings();
 xmlWriterSettings.Encoding = encoding;
 System.Xml.XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings);
 Serializer.Serialize(xmlWriter, this);
 memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
 streamReader = new System.IO.StreamReader(memoryStream);
 return streamReader.ReadToEnd();
}

and this object (gen'd from xsd2code):

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.225")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "Com.Foo.Request")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "Com.Foo.Request", IsNullable = false)]
public partial class REQUEST_GROUP
{

 [EditorBrowsable(EditorBrowsableState.Never)]
 private List<REQUESTING_PARTY> rEQUESTING_PARTYField;

 [EditorBrowsable(EditorBrowsableState.Never)]
 private RECEIVING_PARTY rECEIVING_PARTYField;

 [EditorBrowsable(EditorBrowsableState.Never)]
 private SUBMITTING_PARTY sUBMITTING_PARTYField;

 [EditorBrowsable(EditorBrowsableState.Never)]
 private REQUEST rEQUESTField;

 [EditorBrowsable(EditorBrowsableState.Never)]
 private string iDField;

 public REQUEST_GROUP()
 {
  this.rEQUESTField = new REQUEST();
  this.sUBMITTING_PARTYField = new SUBMITTING_PARTY();
  this.rECEIVING_PARTYField = new RECEIVING_PARTY();
  this.rEQUESTING_PARTYField = new List<REQUESTING_PARTY>();
  this.IDField = "2.1";
 }
}

Output from the Serialize with an encode of utf-8:

<?xml version="1.0" encoding="utf-8"?> <REQUEST_GROUP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="2.1" xmlns="Com.Foo.Request"> <RECEIVING_PARTY /> <SUBMITTING_PARTY /> <REQUEST LoginAccountIdentifier="xxx" LoginAccountPassword="yyy" _RecordIdentifier="" _JobIdentifier=""> <REQUESTDATA> <PROPERTY_INFORMATION_REQUEST _SpecialInstructionsDescription="" _ActionType="Submit"> <_DATA_PRODUCT _ShortSubjectReport="Y" /> <_PROPERTY_CRITERIA _City="Sunshine City" _StreetAddress2="" _StreetAddress="123 Main Street" _State="CA" _PostalCode="12345"> <PARSED_STREET_ADDRESS /> </_PROPERTY_CRITERIA> <_SEARCH_CRITERIA /> <_RESPONSE_CRITERIA /> </PROPERTY_INFORMATION_REQUEST> </REQUESTDATA> </REQUEST> </REQUEST_GROUP>

EDIT Question 1: How do I decorate the class in such a fashion, or manipulate the serializer to get rid of all the namespaces in the REQUEST_GROUP node during processing, NOT post-processing with xslt or regex.

Question 2: Bonus point if you could add the doc type too.

Thank you.

2 Answers 2

7

You can remove the namespaces like this:

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add(string.Empty, string.Empty);
ns.Add(string.Empty, "Com.Foo.Request");
Serializer.Serialize(xmlWriter, this, ns);

As for adding the doctype, I know it's possible to make a custom XmlWriter and just override WriteStartDocument with a method that makes a call to WriteDocType, but I kind of hope someone else knows an easier way than that.

EDIT: Incidentally, I strongly recommend using using:

using(System.Xml.XmlWriter xmlWriter = XmlWriter.Create(etc.))
{
  // use it here.
}

It automatically handles tidying up of the streams by calling the Dispose method when the block ends.

Sign up to request clarification or add additional context in comments.

8 Comments

@Flynn1179 - most namespaces were removed BUT there is still the xmlns:q1="Com.Foo.Request" in the REQUEST_GROUP, and as a by product all nodes are prefaced by <q1:xxx
I don't see any reference to a q1 namespace in the question.. where's that coming from?
@SPATEN to fix that, also add ns.Add("", "Com.Foo.Request"); - then the namespace is without an alias.
@Flynn1179 - XmlSerializer invents it as an alias to use for "Com.Foo.Request"; by default it aliases everything it needs, in case it needs them multiple times
Ah yeah, forgot about that one. Sorry. I'll update the answer.
|
4

If you just want to remove the namespace aliases, then as already shown you can use XmlSerializerNamespaces to force XmlSerializer to use the namespace explicitly (i.e. xmlns="blah") on each element, rather than declaring an alias and using the alias instead.

However, regardless of what you do with the aliases, the fundamental name of that element is REQUEST_GROUP in the Com.Foo.Request namespace. You can't remove the namespace completely without that representing a breaking change to the underlying data - i.e. somebody somewhere is going to get an exception (due to getting data it didn't expect - specifically REQUEST_GROUP in the root namespace). In C# terms, it is the difference between System.String and My.Custom.String - sure, they are both called String, but that is just their local name.

If you want to remove all traces of the namespace, then a pragmatic option would be to edit away the Namespace=... entries from [XmlRoot(...)] and [XmlType(...)] (plus anywhere else that isn't shown in the example).

If the types are outside of your control, you can also do this at runtime using XmlAttributeOverrides - but a caveat: if you create an XmlSerializer using XmlAttributeOverrides you must cache and re-use it - otherwise your AppDomain will leak (it creates assemblies on the fly per serializer in this mode, and assemblies cannot be unloaded).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.