如何使用XmlSerializer将对象集合序列化

4

以下是我迄今为止与由第三方DLL返回的XmlDocument一起使用的步骤:

  1. 我将XmlDocument保存为SegmentationSummary.xml。
  2. 我使用XSD.exe创建了SegmentationSummary.xsd。
  3. 我使用XSD.exe创建了SegmentationSummary.cs。

以下是SegmentationSummary.cs的示例。请注意,ShmResult是根节点表示。

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "omitted")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "omitted", IsNullable = false)]
public partial class ShmResult
{
    private ShmResultDownloadDetail[] downloadDetailField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("DownloadDetail")]
    public ShmResultDownloadDetail[] DownloadDetail
    {
        get
        {
            return this.downloadDetailField;
        }
        set
        {
            this.downloadDetailField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "omitted")]
public partial class ShmResultDownloadDetail
{
    private string modelCodeField;

    /// <remarks/>
    public string ModelCode
    {
        get
        {
            return this.modelCodeField;
        }
        set
        {
            this.modelCodeField = value;
        }
    }
}

现在,我想使用它来读取XmlDocument并开始使用SegmentationSummary.cs中的类。这是我编写的代码:

private XmlDocument _document;
SegmentationSummary.ShmResult _Result;
    private void LoadXML()
    {
        XmlReader xmlRdr = new XmlNodeReader(_document);
        System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(SegmentationSummary.ShmResult));
        _Result = (SegmentationSummary.ShmResult)s.Deserialize(xmlRdr);
    }

当执行LoadXML()时,我会遇到以下类型的异常:
测试方法SegmentationSummaryHandlerTest.TestMethod1引发了异常:System.InvalidOperationException: 无法生成临时类(result = 1)。错误CS0030:无法将类型'MERC.AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail []'转换为'MERC.AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail'。错误CS0029:无法隐式将类型'MERC.AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail'转换为'MERC.AIRCAT.SHMCoreInterface.SegmentationSummary.ShmResultDownloadDetail []'
现在,http://msdn.microsoft.com/en-us/library/ms950721.aspx上的常见问题解答如下:
问:如何序列化对象集合?
答:当集合包含未在XmlSerializer构造函数中声明的类型时,XmlSerializer会抛出异常。您可以:
1.通过传递Type[]来向序列化程序声明类型,以便在集合中使用。
或者
2.实现一个从System.Collections.CollectionBase派生的强类型集合,并使用与Add()方法匹配的索引器。
我的问题是:哪种方法最好,我该如何实现解决方案?

我尝试创建一个Type[]数组,就像这样: Type[] serializedTypes = new Type[] { typeof(SegmentationSummary.Time), typeof(SegmentationSummary.TrendGap), typeof(SegmentationSummary.ShmResultAirDropSummaryAirDrop), typeof(SegmentationSummary.ShmResultSortieSummarySortie) }; System.Xml.Serialization.XmlSerializer s = new System.Xml.Serialization.XmlSerializer(typeof(SegmentationSummary.ShmResult), serializedTypes); 但我仍然收到相同的错误消息。 - Hillarie
你使用的是哪个版本的.NET?此外,请不要让我们猜测XML的样子。请发布示例XML和实际的XSD文件。 - John Saunders
抱歉,John,我正在使用.NET 2.0。我会发布一个XML示例。我想我只需使用“回答你的问题”来附加额外的信息。 - Hillarie
4个回答

3

我遇到了类似的问题。

序列化嵌套的非绑定元素存在问题。 这里有一个解释。

为了解决这个问题,我从xsd中删除了maxoccurs="unbounded"并重新生成了类文件。之后序列化工作正常了。


1

我一直使用的是选项2,所以对于你来说,类似这样的东西可能会起作用:

public class ShmResult : List<ShmResultDownloadDetail> { }

0

微软这里有一个漏洞。它自2003年以来就存在了。我知道这个帖子很旧,但是对于其他人来说,他们可能会在这个问题上碰壁。XSD生成是错误的。在上面的步骤中,使用xsd.exe从xml生成xsd看起来是错误的。我使用了一个叫做trang(开源java)的工具,你可以用它来创建xsd。事实上,你可以使用多个XML文件来创建它。然后,使用xsd.exe来创建.cs文件。这个方法可行。


0

我和你遇到了同样的问题:

  1. 我使用xsd.exe从XML生成了XSD。
  2. 我使用xsd.exe和第一步得到的模式生成了类(们)。
  3. 在尝试将此类用作XMLSerializer构造函数的类型后,我收到了以下异常消息(伪消息):

System.InvalidOperationException:无法生成临时类(result=1)。错误CS0030:无法将Type1 []转换为Type1。

此外,xsd.exe生成的结果类具有矩阵数据类型(Type[][]),这实际上是我的主要关注点。

一旦我使用类型数组创建了XMLSerializer构造函数,该数组可以位于集合内部,我还通过从模式中的几个元素中删除maxoccurs="unbounded"来修改了我的xsd文件。新的生成过程给了我一个新的类。在尝试在XMLSerializer中使用新生成的类之后,一切都很好。

因此,我建议您声明类型数组(可能是集合的一部分),并将其引入XMLSerializer构造函数。此外,请从生成的模式中删除某些元素的maxoccurs="unbounded"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接