Lots of folks have asked me how to add various XMLism like XML Namespace prefixes to the serialized output of a SyndicationFeed. This is actually easy to do once you know the trick but it's admittedly not the most obvious thing in the world.
The thing to remember is that the System.Xml stack treats prefix declarations as special kinds of attributes. If you want to emit an XML namespace declaration of xmlns:contoso=http://schemas.contoso.com you need to emit attribute whose name is the prefix you're declaring (e.g. "contoso"), whose value is the namespace URI that corresponds to the prefix (e.g. 'http://schemas.contoso.com'). This attribute needs to be in the special XML namespace declaration namespace (!) of http://www.w3.org/2000/xmlns/
Since SyndicationFeed supports additional XML attributes through the AttributeExtensions property, you can do this on SyndicationFeed as follows (using the C# 3.0 collection initializer syntax, natch):
SyndicationFeed feed = new SyndicationFeed()
{
AttributeExtensions =
{
{ new XmlQualifiedName("contoso", "http://www.w3.org/2000/xmlns/"), "http://schemas.constoso.com" }
}
};
If you like syntactic sugar, here are a few extension methods that add a helper function to all of the OM constructs that support attribute extensibility:
using System;
using System.Xml;
using System.ServiceModel.Syndication;
namespace Samples
{
public static class SyndicationExtensions
{
public static void DeclareNamespace(this SyndicationFeed feed, string prefix, string nsUri)
{
feed.AttributeExtensions.Add(new XmlQualifiedName( prefix, "http://www.w3.org/2000/xmlns/" ), nsUri);
}
public static void DeclareNamespace(this SyndicationItem item, string prefix, string nsUri)
{
item.AttributeExtensions.Add(new XmlQualifiedName(prefix, "http://www.w3.org/2000/xmlns/"), nsUri);
}
public static void DeclareNamespace(this SyndicationCategory category, string prefix, string nsUri)
{
category.AttributeExtensions.Add(new XmlQualifiedName(prefix, "http://www.w3.org/2000/xmlns/"), nsUri);
}
public static void DeclareNamespace(this SyndicationLink link, string prefix, string nsUri)
{
link.AttributeExtensions.Add(new XmlQualifiedName(prefix, "http://www.w3.org/2000/xmlns/"), nsUri);
}
public static void DeclareNamespace(this SyndicationPerson person, string prefix, string nsUri)
{
person.AttributeExtensions.Add(new XmlQualifiedName(prefix, "http://www.w3.org/2000/xmlns/"), nsUri);
}
}
}
On a side note, I'm becoming a huge fan of extension methods. They are not perfect, but I expect that their existence will have a pretty substantial impact on the way the internals of the framework get factored in future versions...