有没有办法在序列化简单列表时指定标签名称。
一般来说,根据具体情况,它可能会起作用。请参阅 MSDN 的 How to: Specify an Alternate Element Name for an XML Stream。那里的示例涉及覆盖特定字段的序列化,但也可以使用相同的技术来覆盖整个类型名称。
但这对我来说似乎很麻烦。相反,为什么不直接处理序列化:
private static string SerializeByLinqAndToString<T>(
List<T> data, string rootName, string elementName)
{
XDocument document = new XDocument(
new XElement(rootName, data.Select(s => new XElement(elementName, s))));
return SaveXmlToString(document);
}
private static string SaveXmlToString(XDocument document)
{
StringBuilder sb = new StringBuilder();
using (XmlWriter xmlWriter = XmlWriter.Create(sb,
new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }))
{
document.Save(xmlWriter);
}
return sb.ToString();
}
这样调用:
SomeConfiguration config = ...; // initialize as desired
string result = SerializeByLinq(config.Bugs, "bug", "bugs");
以上内容仅适用于字符串列表或类型列表,其中元素内容可以只是在类型实例上调用ToString() 的结果。
在处理复杂类型时,使用 .NET 中成熟的序列化功能可能是值得的,但如果您只有一个简单的字符串列表,则 LINQ-to-XML 功能非常方便。
如果您确实有更复杂的类型,您可以将每个列表元素转换为 DOM 的 XElement 并将其序列化:
private static string SerializeByLinq<T>(
List<T> data, string rootName, string elementName = null)
{
XDocument document = new XDocument(
new XElement(rootName, data.Select(t =>
ElementFromText(SerializeObject(t), elementName)
)));
return SaveXmlToString(document);
}
private static XElement ElementFromText(string xml, string name = null)
{
StringReader reader = new StringReader(xml);
XElement result = XElement.Load(reader);
if (!string.IsNullOrEmpty(name))
{
result.Name = name;
}
return result;
}
private static string SerializeObject<T>(T o)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
StringWriter textWriter = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(textWriter,
new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }))
{
xmlSerializer.Serialize(writer, o,
new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty}));
}
return textWriter.ToString();
}
在第二个示例中,您可以省略子元素的元素名称,它只会使用已设置的类型(例如类型名称,或任何 [XmlRoot] 设置为)。