Currently I am using XML to store many data and when creating those XML files I would like to reduce it is size to the minimum I can.
How could I override the XmlWriter function (WriteEndElement) so instead of saving it like:
<thisElement someAttribute="blabla" />
It will be saved like:
<thisElement someAttribute="blabla"/>
UPDATE:
I am trying to find a way to acomplish this by using:
public override void WriteEndElement()
But I can't the the current WriteEndElement function to know what I have to change on it and if it is even possible.
I'm afraid it's not possible without rewriting significant portions of code. The space is hardcoded in the internal classes and not configurable.
e.g., Code snippet of the internal XmlEncodedRawTextWriter.WriteEndElement() method.
internal override void WriteEndElement(string prefix, string localName, string ns)
{
// snip...
else
{
this.bufPos--;
this.bufChars[this.bufPos++] = ' '; // the space is hard coded
this.bufChars[this.bufPos++] = '/';
this.bufChars[this.bufPos++] = '>';
}
}
Some options that you have that I can think of are to parse the outputted XML to search for the closing tags to remove the space manually, implement your own XML writer so it doesn't include this space, or write a wrapper class to use reflection to modify the internal buffers when the end element is written.
Here's an extension method which could do that. Just be warned, this is not portable. Nor is it guaranteed to work for all cases though it seems to work for simple cases. I don't think what is done here would corrupt the state of the writer but, use at your own risk.
public static class XmlWriterExtensions
{
private static readonly Func<XmlWriter, object> get_writer;
private static readonly Func<object, char[]> get_bufChars;
private static readonly Func<object, int> get_bufPos;
private static readonly Action<object, int> set_bufPos;
static XmlWriterExtensions()
{
var asm = Assembly.GetAssembly(typeof(XmlWriter));
var xmlWellFormedWriterType = asm.GetType("System.Xml.XmlWellFormedWriter");
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
var writerField = xmlWellFormedWriterType.GetField("writer", flags);
get_writer = w => writerField.GetValue(w);
var xmlEncodedRawTextWriterType = asm.GetType("System.Xml.XmlEncodedRawTextWriter");
var bufCharsField = xmlEncodedRawTextWriterType.GetField("bufChars", flags);
var bufPosField = xmlEncodedRawTextWriterType.GetField("bufPos", flags);
get_bufChars = w => (char[])bufCharsField.GetValue(w);
get_bufPos = w => (int)bufPosField.GetValue(w);
set_bufPos = (w, i) => bufPosField.SetValue(w, i);
}
public static void TrimElementEnd(this XmlWriter writer)
{
var internalWriter = get_writer(writer);
char[] bufChars = get_bufChars(internalWriter);
int bufPos = get_bufPos(internalWriter);
if (bufPos > 3 && bufChars[bufPos - 3] == ' ' && bufChars[bufPos - 2] == '/' && bufChars[bufPos - 1] == '>')
{
bufChars[bufPos - 3] = '/';
bufChars[bufPos - 2] = '>';
bufPos--;
set_bufPos(internalWriter, bufPos);
}
}
}
// usage:
Console.OutputEncoding = Encoding.UTF8;
using (var writer = XmlWriter.Create(Console.Out))
{
writer.WriteStartElement("Foo");
writer.WriteElementString("Bar", null);
writer.TrimElementEnd();
writer.WriteElementString("Baz", null);
writer.WriteEndElement();
}
<?xml version="1.0" encoding="utf-8"?><Foo><Bar/><Baz /></Foo>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With