2011-01-05 6 views
3

Derzeit verwende ich XML, um viele Daten zu speichern, und wenn ich diese XML-Dateien erstelle, möchte ich die Größe auf ein Minimum reduzieren.Entfernen Sie den Platz des Endelements?

Wie konnte ich die XmlWriter-Funktion (WriteEndElement) außer Kraft setzen, so anstatt sie wie zu sparen:

<thisElement someAttribute="blabla"/> 

UPDATE:

I

<thisElement someAttribute="blabla" /> 

Es wird wie gespeichert werden Ich versuche einen Weg zu finden, dies zu erreichen, indem ich folgendes benutze:

public override void WriteEndElement() 

Aber ich kann nicht die aktuelle WriteEndElement Funktion wissen, was ich daran ändern muss und ob es überhaupt möglich ist.

+0

Standard-Komprimierung wird nicht funktionieren? Wenn nicht, werde ich eine Antwort finden. – Amy

+0

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

+0

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)'. –

Antwort

1

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> 
+0

Das ist was Ich habe gerade den analysierten XML-Code analysiert die schließenden Tags, um den Platz zu entfernen. – Guapo

+0

@Guapo: Bleib dran, ich werde versuchen, die letzte Option zu schreiben. Es ist möglich, aber sehr hackisch. –

+0

@Jeff Ich freue mich darauf, es wäre ein Segen, es umgesetzt zu haben. – Guapo

Verwandte Themen