代码之家  ›  专栏  ›  技术社区  ›  Jez

使用C XmlSerializer反序列化泛型列表时出现问题

  •  0
  • Jez  · 技术社区  · 15 年前

    我用微软的.NET XML序列化程序遇到了一些困难。我正试图将一些XML反序列化为一个对象,如果我使用一个对象,这很好,但是当一个人将一个对象放入一个列表并尝试对其进行序列化/反序列化时,问题就出现了。首先,这里是一个示例C Windows控制台程序来说明问题:

    http://pastebin.com/m22e6e275

    如果类“foo”被序列化为根元素,则行为良好,如预期的那样-jeznamespace xmlns将应用于根foo元素,并且反序列化也会很好地进行。但是,如果我创建一个列表并序列化它,那么xmlserializer: -创建arrayoffoo的根元素 -将foo元素作为该元素的子元素 -将foo的每个子级的xmlns设置为jeznamespace命名空间!

    我对前两个没意见,但第三个似乎很生气…也许是XML序列化程序中的错误?我有办法处理这种行为吗?我不想为foo的每个子级指定名称空间,我只想为foo指定名称空间。如果我这样做,目前,xmlserializer没有正确反序列化类-它只是跳过jeznamespace xmlns集的任何foo元素。我必须将所有子元素设置为具有该xmln。

    我希望得到的是xmlserializer生成如下内容:

    <ArrayOfFoo>
        <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
            <Field1>hello</Field1>
            <Field2>world</Field2>
        </Foo>
        <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
            <Field1>aaa</Field1>
            <Field2>bbb</Field2>
        </Foo>
    </ArrayOfFoo>
    

    …然后让XMLSerializer能够将其正确反序列化到列表中。你知道我怎么做吗?

    1 回复  |  直到 15 年前
        1
  •  3
  •   Pavel Minaev    15 年前

    您的代码有两个属性 Foo 据我所知,您在这里尝试关联一个名称空间:

     [XmlRootAttribute(Namespace="http://schemas.datacontract.org/2004/07/JezNamespace",
                       IsNullable=false)]
     [XmlTypeAttribute(AnonymousType=true,
                       Namespace="http://schemas.datacontract.org/2004/07/JezNamespace")]
    

    第一个简单地被忽略,因为在您的场景中 不是根元素。第二个名称空间并不像您想象的那样——它中的名称空间是 XSD型 ,而不是元素本身的命名空间。

    要指定元素的名称和命名空间,您需要使用 XmlArrayItemAttribute List<Foo> 父类的属性(哦,您将需要该父类):

    public class FooParent
    {
        [XmlArrayItem(ElementName="Foo",
                      Namespace="http://schemas.datacontract.org/2004/07/JezNamespace")]
        public List<Foo> Foos { get; private set; }
    }
    

    这将产生:

    <FooParent>
      <Foos>
        <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
          <Field1>hello</Field1>
          <Field2>world</Field2>
        </Foo>
        ...
    

    或者,如果你不想要的话 Foos 中间元件,你可以更换 XmlArrayItem 在上面的代码中 XmlElement . 在这种情况下,输出XML如下所示:

    <FooParent>
      <Foo xmlns="http://schemas.datacontract.org/2004/07/JezNamespace">
        <Field1>hello</Field1>
        <Field2>world</Field2>
      </Foo>