我希望能够编写没有名称空间、没有XML前导的缩进XML片段,行结尾为\n
,每个片段使用XmlSerializer
,所有片段使用一个XmlWriter
实例.我怎么能做到这一点?
XmlSerializer.Serialize()
在序列化到通用输出流时生成缩进输出,但它使用"\n\r"作为行尾,我找不到如何配置它.
我可以序列化到XmlWriter
,可以对其进行详细配置,但似乎只有在输出完整的单个文档而不是多个文档片段时,配置才起作用,因为XmlSerializer
将抛出异常ConformanceLevel.Fragment
:
无法在使用ConformanceLevel.Fragment创建的编写器上调用WriteStartDocument
而且,如果我调用XmlWriter.WriteWhitespace("");
作为变通方法,缩进将被禁用. 具体来说,如果我像这样创建一个XmlWriter
:
XmlWriter xw = XmlWriter.Create(System.Console.Out, new XmlWriterSettings()
{
ConformanceLevel = ConformanceLevel.Fragment,
NamespaceHandling = NamespaceHandling.Default,
NewLineChars = "\n",
Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), // supress BOM
Indent = true,
NewLineHandling = NewLineHandling.Replace,
OmitXmlDeclaration = true,
WriteEndDocumentOnClose = false,
CloseOutput = false,
CheckCharacters = false,
NewLineOnAttributes = false,
});
MVE
https://dotnetfiddle.net/qGLIlL个
它确实允许我序列化多个对象,而无需 for each 对象创建新的XmlWriter
.但没有凹痕.
<flyingMonkey name="Koko"><limbs><limb name="leg" /><limb name="arm" /><limb name="tail" /><limb name="wing" /></limbs></flyingMonkey>
<flyingMonkey name="New Name"><limbs><limb name="leg" /><limb name="arm" /><limb name="tail" /><limb name="wing" /></limbs></flyingMonkey>
public class Program {
public static void Main()
{
XmlWriter xw = XmlWriter.Create(System.Console.Out, new XmlWriterSettings()
{
ConformanceLevel = ConformanceLevel.Fragment,
NamespaceHandling = NamespaceHandling.Default,
NewLineChars = "\n",
Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), // supress BOM
Indent = true,
NewLineHandling = NewLineHandling.Replace,
OmitXmlDeclaration = true,
WriteEndDocumentOnClose = false,
CloseOutput = false,
CheckCharacters = false,
NewLineOnAttributes = false,
});
var noNamespace = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
// without this line I get an error:
// "无法在使用ConformanceLevel.Fragment创建的编写器上调用WriteStartDocument."
xw.WriteWhitespace("");
FlyingMonkey monkey = FlyingMonkey.Create();
XmlSerializer ser = new XmlSerializer(typeof(FlyingMonkey), defaultNamespace: null);
ser.Serialize(xw, monkey, noNamespace);
xw.WriteWhitespace("\n\n");
monkey.name = "New Name";
ser.Serialize(xw, monkey, noNamespace);
}
}
[System.Xml.Serialization.XmlTypeAttribute(TypeName = "flyingMonkey", Namespace=null)]
public class FlyingMonkey
{
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name;
public Limb[] limbs;
public static FlyingMonkey Create() =>
new FlyingMonkey()
{
name = "Koko",
limbs = new Limb[]
{
new Limb() { name = "leg" }, new Limb() { name = "arm" },
new Limb() { name = "tail" }, new Limb() { name = "wing" },
}
};
}
[System.Xml.Serialization.XmlTypeAttribute(TypeName = "limb", Namespace=null)]
public class Limb
{
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name;
}
有几分管用:
XmlWriter xw = XmlWriter.Create(System.Console.Out, new XmlWriterSettings()
{
ConformanceLevel = ConformanceLevel.Auto,
NamespaceHandling = NamespaceHandling.Default,
NewLineChars = "\n",
Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), // supress BOM
Indent = true,
NewLineHandling = NewLineHandling.Replace,
OmitXmlDeclaration = true,
WriteEndDocumentOnClose = false,
CloseOutput = false,
CheckCharacters = false,
NewLineOnAttributes = false,
});
var noNamespace = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });
// This is not needed anymore. If I invoke that, it will kill indentation for some reason.
// xw.WriteWhitespace("");
FlyingMonkey monkey = FlyingMonkey.Create();
XmlSerializer ser = new XmlSerializer(typeof(FlyingMonkey), defaultNamespace: null);
ser.Serialize(xw, monkey, noNamespace);
// xw.WriteWhitespace("\n\n");
// monkey.name = "New Name";
// ser.Serialize(xw, monkey, noNamespace); // this second serialization throws InvalidOperationException
它以正确的行尾打印,但不允许您将另一个对象写入同一个XmlWriter实例.
<flyingMonkey name="Koko">
<limbs>
<limb name="leg" />
<limb name="arm" />
<limb name="tail" />
<limb name="wing" />
</limbs>
</flyingMonkey>
我想要重用我的XmlWriter
的单个实例,因为我需要编写多达XmlWriter
k个元素,并且 for each 元素创建XmlWriter
会增加大量开销