【问题标题】:C# XmlSerializer and a collection of different tag names [UWP]C# XmlSerializer 和不同标签名称的集合 [UWP]
【发布时间】:2017-12-04 17:00:49
【问题描述】:

今天我从第 3 方后端获得了更新的 XML 内容,并且不得不更改我们基于 XmlSerializer 的解析代码以符合新字段。不幸的是,我发现引入了一组类似的标签,但行为很奇怪:

<old-root>
  ...
  <contacts>
    <John>Feel happy</John>
    <Mary>Will be away for 2 hours, phone me</Mary>
    <Bob>Do not disturb. I mean it!</Bob>
    ...and so on...
  </contacts>
</root>

到目前为止,我们有一个基于 [XmlElement] 映射的“旧根”解析器类,但我还没有弄清楚如何通过 XML 注释管理类似名称-值对的集合(类似于 [XmlArray ]/[XmlArrayItem] 通常是这样)。我可以通过 [XmlText] 注释获得一个值,但是如何注释该任意标签? “星”模式对 ElementName 无效。

附:我在 .NET 框架的 UWP 子集上。

【问题讨论】:

  • 节点 在设计时是否已知?还是它们是任意节点?
  • @Juan,在设计时不知道确切的名称。这是您从后端收到的联系人列表。
  • 那么你使用属性的策略已经不够用了。我认为您超出了基本的序列化范围,因此您必须实现自定义序列化器/反序列化器。

标签: c# xml uwp


【解决方案1】:

我可以建议以下方法。为您的不同标签使用字典。 XmlSerializer 不能与字典一起使用,所以用XmlIgnore 属性标记它并手动反序列化数据。

[XmlRoot("old-root")]
public class Root
{
    [XmlIgnore]
    public Dictionary<string, string> Contacts { get; set; }
}

首先将 xml 读入 XElement 并从节点 contacts 创建字典。删除那个节点。然后反序列化来自这个XElement 的数据。最后设置之前创建的字典。

var xs = new XmlSerializer(typeof(Root));
Root root = null;
StorageFolder folder = ApplicationData.Current.LocalFolder;

using (var stream = await folder.OpenStreamForReadAsync("test.xml"))
{
    var xml = XElement.Load(stream);
    var contacts = xml.Element("contacts");
    var dict = contacts.Elements().ToDictionary(x => x.Name.LocalName, x => x.Value);
    contacts.Remove();

    root = (Root)xs.Deserialize(xml.CreateReader());
    root.Contacts = dict;
}

这很丑陋,因为从内存消耗的角度和性能的角度来看,它都是低效的。但这很简单。

【讨论】:

  • 对于独立的 .NET 来说可能很好。不幸的是,我在 UWP 子集上。将使用该信息更新问题。
  • 在 IXmlSerializable 的帮助下为 包装类做了非常相似的代码。我还是希望能有更优雅的方式...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多