Ich fürchte, es ist nicht möglich, ohne wesentliche Teile des Codes neu zu schreiben. Der Speicherplatz ist in den internen Klassen fest codiert und nicht konfigurierbar.
z. B. Code-Schnipsel der internen XmlEncodedRawTextWriter.WriteEndElement()
Methode.
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++] = '>';
}
}
Einige Optionen, die Sie, dass ich denken kann, sind die ausgegebenen XML zu analysieren, für das End-Tags zu suchen, um den Raum manuell zu entfernen, Ihre eigenen XML-Writer implementieren, damit es diesen Raum nicht enthält, oder Schreiben Sie eine Wrapper-Klasse, um Reflection zu verwenden, um die internen Puffer zu ändern, wenn das Endelement geschrieben wird.
Hier ist eine Erweiterungsmethode, die das tun könnte. Seien Sie gewarnt, das ist nicht tragbar. Es ist auch nicht garantiert, dass es für alle Fälle funktioniert, obwohl es für einfache Fälle zu funktionieren scheint. Ich denke nicht, was hier getan wird, würde den Zustand des Schreibers beschädigen, aber verwenden Sie auf eigene Gefahr.
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>
Standard-Komprimierung wird nicht funktionieren? Wenn nicht, werde ich eine Antwort finden. – Amy
Die Anwendung, die das XML verwenden wird, wird nicht von uns gemacht und wir haben bereits Änderungen angefordert, aber es ist nicht geplant, es in absehbarer Zeit zu ändern, also tun wir, was wir können, um es zu minimieren :(und die Änderung dieses Speicherplatzes ist Einer davon sind Dateien mit Millionen Einträgen, Dateien mit 200MB, 300MB etwas mehr, aber das ist der aktuelle Durchschnitt – Guapo
Ich weiß, das ist eine komplette Hackidee, aber Sie könnten string ersetzen, indem Sie die ganze Datei in einen String, ' strXML '. run' strXML.Replace ("\"/"", "\" /> ")' darauf. dann 'XElement.Parse (strXML)'. –