There' s a pretty nasty XmlFragmentWriter example up on GDN that uses reflection to mess with the internal state of an XmlTextWriter in order to omit the XML declaration. Yikes.
This is an alternate (better) XmlFragmentWriter that's breaks fewer Commandments. It takes code from Sairama, one of our platform engineers at Corillian, to omit the XmlDecl. I took Sai's stuff and added Kzu's xsi/xsd trick to create XML fragments. Here's XmlFragmentWriter.
Given a class (just an example, don't serialize passwords!):
public class AuthenticationInfo
{
public string Username;
public string Password;
}
Here's the code and an instance serialized using the standard XmlSerializer. Note the Xml Declaration and the XML schema and instance namespace:
<?xml version="1.0"?>
<AuthenticationInfo
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Username>user1</Username>
<Password>pass1</Password>
</AuthenticationInfo>
Standard XmlSerializer fare:
AuthenticationInfo a = new AuthenticationInfo();
a.Username = "user1";
a.Password = "pass1";
XmlSerializer x = new XmlSerializer( typeof(AuthenticationInfo));
XmlTextWriter w2 = new XmlTextWriter(@"c:\bar.xml",null);
w2.Formatting = Formatting.Indented;
x.Serialize( w2, a );
w2.Close();
Here's the same object serialized using our XmlFragmentWriter:
<AuthenticationInfo>
<Username>user1</Username>
<Password>pass1</Password>
</AuthenticationInfo>
And here's how it's used:
AuthenticationInfo a = new AuthenticationInfo();
a.Username = "user1";
a.Password = "pass1";
XmlSerializer f = new XmlSerializer( typeof(AuthenticationInfo));
XmlFragmentWriter w = new XmlFragmentWriter(@"c:\foo.xml",null);
w.Formatting = Formatting.Indented;
f.Serialize( w, a );
w.Close();
And here's the XmlFragmentWriter class:
class XmlFragmentWriter : XmlTextWriter
{
public XmlFragmentWriter(TextWriter w) : base(w){}
public XmlFragmentWriter(Stream w, Encoding encoding) : base(w, encoding) {}
public XmlFragmentWriter(string filename, Encoding encoding) :
base(new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None), encoding){}
bool _skip = false;
public override void WriteStartAttribute( string prefix, string localName, string ns )
{
// STEP 1 - Omits XSD and XSI declarations.
// From Kzu - http://weblogs.asp.net/cazzu/archive/2004/01/23/62141.aspx
if ( prefix == "xmlns" && ( localName == "xsd" || localName == "xsi" ) )
{
_skip = true;
return;
}
base.WriteStartAttribute( prefix, localName, ns );
}
public override void WriteString( string text )
{
if ( _skip ) return;
base.WriteString( text );
}
public override void WriteEndAttribute()
{
if ( _skip )
{
// Reset the flag, so we keep writing.
_skip = false;
return;
}
base.WriteEndAttribute();
}
public override void WriteStartDocument()
{
// STEP 2: Do nothing so we omit the xml declaration.
}
}
Thanks Kzu and Sairama for giving me these pieces to assemble. I tell you, System.Xml is slick slick slick. Updated with a cleaner solution.
(You can also get rid of the namespaces with another trick but it smells hacky and I don't know what the side effects would be if your document had other namespaces)
Now playing: Akon - Show Out
Hosting By