恐怕没有重写大量代码是不可能的。空格是硬编码在内部类中的,无法配置。
例如,内部XmlEncodedRawTextWriter.WriteEndElement()
方法的代码片段。
internal override void WriteEndElement(string prefix, string localName, string ns)
{
else
{
this.bufPos--;
this.bufChars[this.bufPos++] = ' ';
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);
}
}
}
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>
strXML
中。在其上运行strXML.Replace("\" />", "\"/>")
。然后使用XElement.Parse(strXML)
。 - jb.