First time here? Check out the site's "greatest hits" or read a post from the archives. Feel free to leave a comment or ask a question, and consider subscribing to the latest posts via RSS or e-mail. Thanks for visiting!
Do you Tweet? Follow me on Twitter @shanselman or learn how to use Twitter!
« Visual Studio 2005 Keyboard Locks Up | Main | Programmatically adding Mime Types to II... »

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

Tracked by:
"Using the XmlSerializer to Read and Write XML Fragments" (ComputerZen.com - Sco... [Trackback]
"Leaning on the Language and Leaning on the Libraries" (ComputerZen.com - Scott ... [Trackback]


Friday, August 05, 2005 12:57:24 AM (Pacific Standard Time, UTC-08:00)
its just freaky howe we manage to stumble into exactly same things with few hours difference. first ruby unit testing now this.... lightweight solution:

XmlSerializerNamespaces _ns=new XmlSerializerNamespaces(); // can be static private
_ns.Add( "", "" );
_xsMyType.Serialize(writer,obj,_ns);

same effect on output.
Max S
Friday, August 05, 2005 5:24:13 AM (Pacific Standard Time, UTC-08:00)
Getting rid of the xml declaration and xsi / xsd namespaces is so hot right now! I just wrote almost the exact same thing yesterday. Creepy.
Friday, August 05, 2005 6:45:20 AM (Pacific Standard Time, UTC-08:00)
I needed this in VB.NET, so I've ported it. You can find the port at http://www.blowery.org/code/XmlFragmentWriter-VB.NET.zip

Thanks!
Friday, August 05, 2005 8:05:16 AM (Pacific Standard Time, UTC-08:00)
Since you're on the topic - is this approach a bad idea?

public class SampleFragmentXmlTextWriter: XmlTextWriter
{
public SampleFragmentXmlTextWriter( TextWriter w ) : base( w ) {}
public SampleFragmentXmlTextWriter( Stream w, Encoding encoding ) : base( w, encoding ) {}
public SampleFragmentXmlTextWriter( string filename, Encoding encoding ) : base( filename, encoding ) {}

public override void WriteStartDocument()
{
// do nothing so we don't end up with an xml declaration
}
}
buk
Friday, August 05, 2005 8:21:59 AM (Pacific Standard Time, UTC-08:00)
Max S. - That's the "hacky" solution that I linked to in this post.
Friday, August 05, 2005 8:38:14 AM (Pacific Standard Time, UTC-08:00)
Buk - I like that also! That's even cleaner!
Friday, August 05, 2005 12:51:45 PM (Pacific Standard Time, UTC-08:00)
Which is cleaner that the hack I threw together to shift a utf-16 dataset schema into a utf-8 schema that xsd.exe could turn into a nice dataset class for me..

XmlDocument doc = db.ExtractSchemaForStoredProcedure(textBox1.Text,textBox3.Text,textBox2.Text);
XmlDocument newdoc = new XmlDocument();
newdoc.LoadXml(doc.DocumentElement.OuterXml);
MessageBox.Show(newdoc.OuterXml);
create a new declaration so we can switch to utf-8 (xsd.exe likes this)
XmlDeclaration decl= newdoc.CreateXmlDeclaration("1.0","UTF-8",null);
XmlElement root = newdoc.DocumentElement;
newdoc.InsertBefore(decl,root);
XmlTextWriter write = new XmlTextWriter(textBox4.Text,System.Text.Encoding.UTF8);
newdoc.WriteTo(write);
write.Flush();
write.Close();
Saturday, August 06, 2005 12:40:29 AM (Pacific Standard Time, UTC-08:00)
Ian - My eyes are literally burning. You've effectively burned my retinas. I hope you're happy.

;)
Saturday, August 06, 2005 9:11:07 PM (Pacific Standard Time, UTC-08:00)
yeah, I didn't like it much either! But look on the bright side - I could've posted one of our stored procedures that happen to be written in COBOL.
That's still hurting my brain, but at least we're dogfooding our own DB!

in all seriousness, any idea WHY xsd.exe doesn't like a standard schema spat out by dataSet.getXMLSchema() (ie with UTF-16 rather than UTF-8 )?
It's very annoying. If it were one or two I'd just switch em by hand but it looks like they'll be creating >400 of the things..
Tuesday, August 09, 2005 7:46:34 PM (Pacific Standard Time, UTC-08:00)
Scott, honestly, your (and mine therefore!) approach looks more hacky to me than just using the XmlNamespaces class. Besides, it works fine and I never saw a side-effect... Dunno...
Tuesday, August 09, 2005 10:18:13 PM (Pacific Standard Time, UTC-08:00)
Another way is to simply create a new document at the beginning of the root element and return with the innerxml.
But this is a cleaner method.
Thanx, Csaba.
Csaba Kabai
Thursday, August 11, 2005 9:43:37 AM (Pacific Standard Time, UTC-08:00)
Let me play too! I posted a sample to gotdotnet about a month ago:

http://www.pickabar.com/blog/archives/2005/07/xml_serializati.html


the key parts being:

public override void WriteStartDocument()
{
return;
}

public override void WriteStartDocument(bool standalone)
{
return;
}
Comments are closed.

Contact

Sponsors

Hosting By

Hot Topics

Tags

Calendar

<November 2009>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Archives

November, 2009 (5)
October, 2009 (19)
September, 2009 (11)
August, 2009 (12)
July, 2009 (21)
June, 2009 (26)
May, 2009 (16)
April, 2009 (13)
March, 2009 (17)
February, 2009 (17)
January, 2009 (18)
December, 2008 (32)
November, 2008 (17)
October, 2008 (22)
September, 2008 (16)
August, 2008 (14)
July, 2008 (25)
June, 2008 (19)
May, 2008 (17)
April, 2008 (17)
March, 2008 (26)
February, 2008 (21)
January, 2008 (28)
December, 2007 (19)
November, 2007 (17)
October, 2007 (31)
September, 2007 (39)
August, 2007 (37)
July, 2007 (43)
June, 2007 (37)
May, 2007 (32)
April, 2007 (38)
March, 2007 (29)
February, 2007 (46)
January, 2007 (31)
December, 2006 (27)
November, 2006 (31)
October, 2006 (32)
September, 2006 (39)
August, 2006 (34)
July, 2006 (40)
June, 2006 (18)
May, 2006 (31)
April, 2006 (34)
March, 2006 (30)
February, 2006 (38)
January, 2006 (44)
December, 2005 (19)
November, 2005 (34)
October, 2005 (24)
September, 2005 (37)
August, 2005 (20)
July, 2005 (24)
June, 2005 (33)
May, 2005 (16)
April, 2005 (22)
March, 2005 (34)
February, 2005 (15)
January, 2005 (37)
December, 2004 (28)
November, 2004 (30)
October, 2004 (34)
September, 2004 (22)
August, 2004 (34)
July, 2004 (18)
June, 2004 (64)
May, 2004 (49)
April, 2004 (21)
March, 2004 (29)
February, 2004 (29)
January, 2004 (36)
December, 2003 (25)
November, 2003 (24)
October, 2003 (59)
September, 2003 (42)
August, 2003 (24)
July, 2003 (44)
June, 2003 (29)
May, 2003 (21)
April, 2003 (30)
March, 2003 (27)
February, 2003 (47)
January, 2003 (50)
December, 2002 (31)
November, 2002 (38)
October, 2002 (44)
September, 2002 (15)
May, 2002 (2)
April, 2002 (4)

Google Ads