TLDR version
I am serializing objects into XML to match a schema provided by a third party. Their validator requires one of the child objects to have a namespace explicitly declared which matches it's ancestor's namespace . The data is complex enough that I don't want to roll my own serializer for this purpose. How can I force the XMLSerializer class to explicitly render a namespace even though it is technically redundant?
Full version
I am running into an issue where the CoreItemsMkt namespace is not rendered by the XMLSerializer. I believe that this is because both the attribute and the namespaces exactly match the ancestor's namespace that it is inheriting from, therefore the serializer omits it - however, the site validator that this file gets submitted to requires it.
For example:
<?xml version="1.0" encoding="utf-8"?>
<FSAMarketsFeed xmlns="http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2">
<FSAFeedHeader xmlns="http://www.fsa.gov.uk/XMLSchema/FSAFeedCommon-v1-2">
[...contents omitted, this item appears once...]
</FSAFeedHeader>
<FSAMarketsFeedMsg>
<CoreItemsMkt xmlns="http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2"> <!--//This namespace is the issue//-->
[...contents omitted, this item appears multiple times...]
</CoreItemsMkt?
</FSAMarketsFeedMsg>
<FSAMarketsFeedMsg>
<CoreItemsMkt xmlns="http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2"> <!--//This namespace is the issue//-->
[...contents omitted, this item appears multiple times...]
</CoreItemsMkt?
</FSAMarketsFeedMsg>
I'm serializing with a method like this:
var path = GetFilePath();
var ns = new XmlSerializerNamespaces();
ns.Add("", "http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2");
var ser = new XmlSerializer(typeof(FSAMarketsFeed));
var settings = new XmlWriterSettings
{ Encoding = Encoding.UTF8, Indent = true, IndentChars = "\t", NamespaceHandling = NamespaceHandling.Default };
using (var writer = XmlWriter.Create(path, settings))
{
ser.Serialize(writer, GetDataToSerialize(), ns);
}
My root class is defined as:
[XmlType(AnonymousType = true)]
[XmlRoot(Namespace = "http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2", IsNullable = false)]
public class FSAMarketsFeed
{
public FSAMarketsFeed()
{
FSAMarketsFeedMsg = new FSAMarketsFeedMsg[0];
}
[XmlElement("FSAFeedHeader", IsNullable = true, Namespace = "http://www.fsa.gov.uk/XMLSchema/FSAFeedCommon-v1-2")]
public FSAFeedHeader FeedHeader { get; set; }
[XmlElement("FSAMarketsFeedMsg")]
public FSAMarketsFeedMsg[] FSAMarketsFeedMsg { get; set; }
}
The working feed header class:
[XmlType(AnonymousType = true)]
public class FSAFeedHeader
{
[XmlElement("FeedTargetSchemaVersion", IsNullable = true)]
public string FeedTargetSchemaVersion { get; set; }
[XmlElement("Submitter", IsNullable = true)]
public Submitter Submit { get; set; }
[XmlElement("ReportDetails", IsNullable = true)]
public ReportDetails ReportDetail { get; set; }
}
The parent Feed Message Class:
[XmlType(AnonymousType = true)]
public class FSAMarketsFeedMsg
{
[XmlElement("CoreItemsMkt", IsNullable = true, Namespace = "http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2")]
public CoreItemsMkt CoreMarket { get; set; }
[XmlElement("Transaction", IsNullable = true)]
public Transaction Trans { get; set; }
}
Finally, the CoreItemsMkt class which is failing to render its namespace:
[XmlType(Namespace = "http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2", AnonymousType = true)]
public class CoreItemsMkt
{
//[... Children omitted ...]]
}
Tried so far:
- Using XMmlType(AnonymousType = true) to try to break the inheritance chain
- Explicitly setting xmlns as an XmlAttributeAttribute w/ a hard coded value.
- Setting and removing XmlType(Namespace = "http://www.fsa.gov.uk/XMLSchema/FSAMarketsFeed-v1-2") on CoreItemsMkt
- Adding and removing XmlElement(Namespace = "the value") on the FSAMArketsFeedMsg's property.
- Implementing ISerializable on CoreItmsMkt (Couldn't quite figure out how to get that to work though.)
- Stack overflow searches - I've found 1 similar question that was answered with "This is unsupported, change your output namespace." Unfortunately, that answer doesn't work for me.
So, without hand rendering this, is there any way to force the XmlSerializer class to render those namespace attributes on CoreItmsMkt?