【问题标题】:Xml Deserialization Fails on Empty ElementXml 反序列化在空元素上失败
【发布时间】:2023-03-30 08:31:02
【问题描述】:

我有一个看起来也很相似的 Xml 文档

<Reports xmlns="">
  <Report>
    <ReportID>1</ReportID>
    <ParameterTemplate />
  </Report>
</Reports>

序列化到这个对象失败

[XmlType(TypeName = "Report")]
public class Report
{
    [XmlElement("ReportID")]
    public int ID { get; set; }

    [XmlElement("ParameterTemplate")]
    public XElement ParameterTemplate { get; set; }
}

它失败是因为空的 ParameterTemplate 元素,因为如果它包含子元素,它会很好地反序列化。

我怎样才能让它工作?

这是我的反序列化代码

var serializer = new XmlSerializer(typeof(Report));
return (Report)serializer.Deserialize(source.CreateReader());

例外是

XmlReader 必须位于 Element 类型的节点上,而不是 EndElement 类型的节点上。

如何使用现有的 xml 进行反序列化?

谢谢 -c

【问题讨论】:

  • 出于兴趣,如果是&lt;ParameterTemplate&gt;&lt;/ParameterTemplate&gt; 可以正常工作吗?
  • 否,但完全删除它确实允许它序列化。
  • 那么您到底想在 XML 文件中的 XElement 中存储什么?好像有点奇怪.....
  • @marc_s,它更像是 XML,但不像 XML 文件的其余部分那样“强类型”。如果报表没有参数,甚至不需要。
  • 为什么不直接添加 [XmlElement(IsNullable=true)]

标签: c# xml exception serialization


【解决方案1】:

看起来XElement 的内容 - 如果 not 为 null - 不能是空的 XML 元素。换句话说,您将无法从您的 Report 类的内存表示/实例中序列化您的示例中的 that XML。

【讨论】:

  • 这就是我得出的结论,我已经与该 XML 的提供者进行了交谈以删除空元素
  • 这看起来像是在第一种情况下没有正确序列化 XML 的症状,这很可能是使用 .NET 1.0 XmlSerializer 完成的。要正确序列化 minOccurs="0" 元素(例如 XML 中不应该存在的元素),您需要在类中添加一个 bool ParameterTemplateSpecified 元素。见stackoverflow.com/questions/2330001/…
【解决方案2】:

您可以在报表类上实现IXmlSerializable 接口并覆盖ReadXml 和WriteXml 方法。

【讨论】:

    【解决方案3】:

    我创建了以下方法来修补 XML 文本:

    Public Function XMLReaderPatch(rawXML As String) As String
        If String.IsNullOrEmpty(rawXML) Then Return rawXML
    
         'Pattern for finding items similar to <name*/> where * may represent whitespace followed by text and/or whitespace
         Dim pattern As String = "<(\S+)(\s[^<|>]*)?/>"
         'Pattern for replacing with items similar to <name*></name> where * may represent whitespace followed by text and/or whitespace
         Dim replacement As String = "<$1$2></$1>"
         Dim rgx As New Text.RegularExpressions.Regex(pattern)
    
         Return rgx.Replace(rawXML, replacement)
     End Function
    

    【讨论】:

      【解决方案4】:

      使用 IsNullable=True

      [XmlType(TypeName = "Report")]
      public class Report
      {
          [XmlElement("ReportID")]
          public int ID { get; set; }
      
          [XmlElement("ParameterTemplate", IsNullable=true)]
          public XElement ParameterTemplate { get; set; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-02
        • 2012-02-25
        • 1970-01-01
        • 2011-06-24
        • 1970-01-01
        • 2011-02-27
        相关资源
        最近更新 更多