gpt4 book ai didi

c# - 有没有办法在序列化类的一部分时保留 XML 属性?

转载 作者:太空狗 更新时间:2023-10-30 01:14:31 35 4
gpt4 key购买 nike

我正在尝试序列化一个类的一部分。我已将 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>

如何让部分类使用上述标签进行序列化?

或者更好的是,在序列化一个简单的 List<object> 时有没有办法指定标签名称? .这样您就可以指定用于列表的标签,而不是使用 <ArrayOfobject>并指定用于数组项的标签而不是 <object>

最佳答案

is there a way to specify tag names when serializing a simple List.

一般来说,根据具体情况,它可能会起作用。请参阅 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] 是设置为)。

关于c# - 有没有办法在序列化类的一部分时保留 XML 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42821364/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com