问题反序列化泛型列表与C#XmlSerializer的

问题反序列化泛型列表与C#XmlSerializer的

问题描述:

我碰到一个有点砖墙与微软的.NET的XmlSerializer的。我试图反序列化一些XML成一个对象,这是好的,如果我使用一个单一的对象,但是当一个人把一个对象转为列表,然后尝试序列化/反序列化问题就来了。首先起来,这里是一个示例C#Windows控制台程序来说明这个问题:

I've come up against a bit of a brick wall with Microsoft's .net XmlSerializer. I'm trying to deserialize some XML into an object, which is fine if I'm using a single object, but the problem comes when one puts an object into a List and tries to serialize/deserialize that. First up, here's a sample C# windows console program to illustrate the problem:

http://pastebin.com/m22e6e275

如果类'富'是序列化为一个根元素,事情的行为罚款,并如预期 - 该JezNamespace XMLNS被施加到根富元件,并发生细反序列化。但是,如果我创建一个列表和序列化,XmlSerializer的:
- 创建ArrayOfFoo
的根元素 - 使富元素作为该元素
的孩子 - 设置每个孩子的XMLNS富到JezNamespace空间!

If the class 'Foo' is serialized as a root element, things behave fine, and as expected - the JezNamespace xmlns is applied to the root Foo element, and deserialization occurs fine. However if I create a List and serialize that, the XmlSerializer: - Creates a root element of ArrayOfFoo - Puts the Foo elements as children of that element - Sets the xmlns of EVERY child of Foo to the JezNamespace namespace!

我行与前两个,但第三人似乎疯了...也许一个错误的XmlSerializer?有一些办法可以对付这种行为?我不希望我的指定的命名空间中富每一个孩子,我只是想指明它美孚。如果我这样做,目前,XmlSerializer的不正确地反序列化类 - 它只是跳过与设置JezNamespace的xmlns任何美孚元素。我必须设置所有的子元素具有的xmlns

I'm OK with the first two, but the third one seems mad... maybe a bug in XmlSerializer? Is there some way I can deal with this behaviour? I don't want to be specifying my namespace for every child of Foo, I just want to specify it for Foo. If I do that, currently, XmlSerializer doesn't deserialize the class properly - it just skips over any Foo element with the JezNamespace xmlns set. I have to set ALL the child elements to have that xmlns.

我想获得的就是XmlSerializer的生成是这样的:

What I'd like to get to is XmlSerializer generating something like:

<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的能够反序列化,适当到列表中。任何想法如何,我可以得到它这样做?

... and then have XmlSerializer be able to deserialize that properly into a List. Any ideas how I can get it doing this?

您的代码对富两个属性code>,到目前为止我所知道的,你放在那里,试图命名空间相关联:

Your code has two attributes on Foo that, so far as I can tell, you've put there to try to associate a namespace:

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

第一个会被忽略,因为在您的方案不是根元素。第二个不很做什么你可能认为它 - 它的名称空间是一个的 XSD类型的,而不是元素本身的命名空间的命名空间

The first one is simply ignored, because in your scenario Foo is not a root element. The second one doesn't quite do what you probably think it does - the namespace in it is a namespace of an XSD type, not namespace of an element itself.

要指定名称和元素的命名空间,你反而需要使用 XmlArrayItemAttribute 列表&LT;富&GT; 父类的属性(哦,你将需要一个父类):

To specify name and namespace of the element, you do instead need to use XmlArrayItemAttribute on the List<Foo> property of a parent class (oh, and you will need that parent class):

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将是这样的:

Alternatively, if you do not want that Foos intermediate element at all, you can replace XmlArrayItem in code above with XmlElement. In this case, the output XML will look like this:

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