【问题标题】:Duplicate values when deserializing xml from external api using built in xml deserialization in C#使用 C# 中的内置 xml 反序列化从外部 api 反序列化 xml 时重复值
【发布时间】:2011-08-18 04:38:35
【问题描述】:

我正在使用内置的 XML 反序列化(不是因为它是我的选择,而是遗留代码)将 xml 反序列化为强类型对象。

注意:我无法控制 xml,它是一个外部 api

问题是 xml 节点已扩展为包含同名的子节点,并且它破坏了序列化。

例如xml如下:

<people>
  <person>
    <id>1234</id>
    <person>
      <name>This is my name</name>
    <person>
   </person>
</people>

以下对象

[XmlType("person")]
public class Person {

  [XmlElement("id")]
  public int Id { get; set; }

  [XmlElement("person")]
  public PersonTitle Title{ get; set; }
}

[XmlType("person")]
pulic class PersonTitle
{
   [XmlElement("name")]
   public string Name { get; set; }
}

这在调用 (T)xmlserializer.Deserialize(stream) 时会引发错误,因为即使 xml 是有效的,名称也会重复。就我个人而言,我不会费心在对象中复制 xml 布局,只是为了在手动反序列化更容易维护时自动反序列化它(尤其是当它一开始就从未被 .net 序列化时)。

但是,我想知道是否有办法解决这个问题,即使这意味着将子对象展平。

我知道这不起作用,但例如:

[XmlType("person")]
public class Person {

  [XmlElement("id")]
  public int Id { get; set; }

  [XmlElement("person/name")]
  public string Title{ get; set; }
}

感谢任何帮助。

【问题讨论】:

    标签: c# asp.net xml xml-serialization


    【解决方案1】:

    最简单的方法可能是在反序列化之前通过 XSLT 转换运行它 - 匹配人员/人员/姓名元素并仅输出人员/姓名部分。然后反序列化结果。

    这是一篇关于在 C# 中应用 XSLT 的 SO 帖子:How to apply an XSLT Stylesheet in C#

    这里是使用 XSLT 替换元素的一个:http://cvalcarcel.wordpress.com/2008/09/06/replacing-arbitrary-xml-located-within-an-xml-document-using-xslt/

    【讨论】:

    • 好的,所以真的没有办法绕过反序列化程序,坚持要求子元素对其父元素进行唯一命名?
    • 尽管我对此表示怀疑,但也许可以向 person 类添加一个 Name 属性和一个适当归属的 NestedPerson 属性,并使所有属性在语义上都是可选的。这可能会欺骗 XmlSerializer 创建一个具有所有其他属性的外部人员实例,并在它的 NestedPerson 属性中创建另一个人员实例,其中仅设置了 name 属性。但这似乎比 XSLT 预处理器更像是一种 hack。
    • 感谢您的意见。因为我的真实世界情况有一个完整的对象库,其中反序列化完全由注释运行,所以我将把它留得更久。如果我过多地干预实际的服务呼叫,我将有很多需要重新测试。再说一次,我自己不会这样做,但我现在坚持下去。如果我没有得到任何更快的修复,我会标记为答案...再次感谢!
    【解决方案2】:

    在最坏的情况下,您可以编写您喜欢的类(不要因序列化而妥协),然后实现 IXmlSerializable。实现 ReadXml,如果愿意,为 WriteXml 抛出 NotImplementedException。

    【讨论】:

    • 它是为匹配发送给我们的xml而编写的。问题是 XmlSerializer 不喜欢父元素和子元素共享“person”的相同 XmlElement 的事实。只是想知道是否有一种解决方法比重写那里的解析更快。这是一个非常复杂的休息界面,需要几天的工作来重写。
    猜你喜欢
    • 2011-05-12
    • 2013-04-28
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多