I am looking at the XMPP protocol and testing some basic interaction with a server. XMPP interacts by exchanging XML forward and backwards, but this XML is part of an ongoing stream, effectively building a document as it goes.
I have tried to reproduce this using an XmlWriter and although I can create the Xml almost exactly as required, I can't seem to prevent the writer from closing the Xml Element. For example to open the connection you send a <stream:stream ... >
element (to be closed at some later point in the interaction). Using an XmlWriter will always close this element such as: <stream:stream ... />
which I don't want because sending the close />
will cause the server to close the stream.
Is there a way to get an XmlWriter to leave the element "open" but still retrieve the data contained within? Of course I can just do a string replace on the element to get rid of the '/' but I'd prefer to find a neater method of doing this if possible.
The initial message to send to the server looks like this:
<?xml version="1.0" encoding="utf-8"?><stream:stream from="email@address.com" to="address.com" version="1.0" xml:lang="en" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" >
So far my code is:
private string CreateStreamHeader(string from, string to, double version)
{
Encoding encoding = new UTF8Encoding(false);
var sb = new StringBuilder();
var settings = new XmlWriterSettings();
settings.Encoding = encoding;
using(var output = new StringWriterWithEncoding(sb, encoding))
{
using(XmlWriter writer = XmlWriter.Create(output, settings))
{
writer.WriteStartDocument();
writer.WriteStartElement("stream", "stream", "http://etherx.jabber.org/streams");
writer.WriteAttributeString("from", from);
writer.WriteAttributeString("to", to);
writer.WriteAttributeString("version", version.ToString("0.0"));
writer.WriteAttributeString("xml", "lang", null, "en");
writer.WriteAttributeString("xmlns", "jabber:client");
}
}
return sb.ToString();
}
And this code produces:
<?xml version="1.0" encoding="utf-8"?><stream:stream from="email@address.com" to="address.com" version="1.0" xml:lang="en" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" />
<-- note the /> here
Note: the StringWriterWithEncoding is the one explained in this post