我正在尝试序列化课程的一部分。我已将XML属性添加到类成员,以便无论命名属性如何,都正确命名生成的XML标记以匹配规范。序列化主类时,这可以正常工作。但是,如果只想序列化该类的一部分,则会丢失XML属性,并且名称会恢复为默认值。仅对类的一部分进行序列化时,是否可以保留XML属性?
[XmlRoot ("someConfiguration")]
public class SomeConfiguration
{
[XmlArray("bugs")]
[XmlArrayItem("bug")]
public List<string> Bugs { get; set; }
}
当我序列化整个类时,我得到了这个(这正是我所期望的):
<someConfiguration>
<bugs>
<bug>Bug1</bug>
<bug>Bug2</bug>
<bug>Bug3</bug>
</bugs>
</someConfiguration>
如果我只是尝试序列化该类的“ Bugs”部分,则会得到此提示(请注意,更改标记名的XML属性都将被忽略):
<ArrayOfString>
<string>Bug1</string>
<string>Bug2</string>
<string>Bug3</string>
</ArrayOfString>
我需要得到这个:
<bugs>
<bug>Bug1</bug>
<bug>Bug2</bug>
<bug>Bug3</bug>
</bugs>
我如何获得偏类以使用以上标签进行序列化?
或者更好的是,在序列化simple时是否有一种方法可以指定标签名称List<object>
。这样您就可以指定用于列表的标记而不是使用,<ArrayOfobject>
并指定用于数组项的标记而不是<object>
?
序列化简单列表时,有没有一种方法可以指定标签名称。
通常,根据实际情况,有可能使它起作用。请参见MSDN的“如何:为XML流指定备用元素名称”。那里的示例涉及覆盖特定字段的序列化,但是也可以使用相同的技术覆盖整个类型名称。
但是对我来说,这似乎很麻烦。相反,为什么不直接处理序列化呢?
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功能非常方便。
如果确实有更复杂的类型,则可以将每个列表元素转换XElement
为DOM的并将其序列化:
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]
设置为的任何内容)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句