Remove end item space?

I am currently using XML to store a lot of data, and when creating these XML files, I would like to reduce the size to the minimum I can.

How can I override the XmlWriter (WriteEndElement) function to save it as:

<thisElement someAttribute="blabla" />

It will be saved as:

<thisElement someAttribute="blabla"/>   

UPDATE:

I am trying to find a way to do this using:

public override void WriteEndElement()

But I can not use the current WriteEndElement function to know what I need to change on it, and if possible.

+3
source share
1 answer

I am afraid that this is not possible without overwriting significant parts of the code. The space is hardcoded in the inner classes and is not customizable.

for example, a code snippet of an internal method XmlEncodedRawTextWriter.WriteEndElement().

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++] = '>';
    }
}

, , - XML , , XML-, .


, . , . , , , . , , , , .

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

Source: https://habr.com/ru/post/1783543/


All Articles