我与微软的.net XmlSerializer对抗了一点砖墙。我正在尝试将一些XML反序列化为一个对象,如果我使用单个对象,这很好,但是当一个对象放入一个List并尝试序列化/反序列化时就会出现问题。首先,这是一个示例C#windows控制台程序来说明问题:
如果将类'Foo'序列化为根元素,则事情表现良好,并且正如预期的那样 - 将JezNamespace xmlns应用于根Foo元素,并且反序列化很好。但是,如果我创建一个List并序列化它,那么XmlSerializer: - 创建ArrayOfFoo的根元素 - 将Foo元素作为该元素的子元素 - 将Foo的每个子节点的xmlns设置为JezNamespace命名空间!
前两个我没问题,但第三个看起来很疯狂......也许是XmlSerializer中的一个错误?有什么方法可以处理这种行为吗?我不想为Foo的每个孩子指定我的命名空间,我只想为Foo指定它。如果我这样做,目前,XmlSerializer没有正确反序列化它 - 它只是跳过任何设置了JezNamespace xmlns的Foo元素。我必须将所有子元素设置为具有该xmlns。
我想要的是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能够将其正确地反序列化为List。我有什么想法可以做到这一点吗?
答案 0 :(得分:3)
你的代码在Foo
上有两个属性,据我所知,你已经把它放在那里试图关联命名空间:
[XmlRootAttribute(Namespace="http://schemas.datacontract.org/2004/07/JezNamespace",
IsNullable=false)]
[XmlTypeAttribute(AnonymousType=true,
Namespace="http://schemas.datacontract.org/2004/07/JezNamespace")]
第一个被忽略,因为在您的场景中Foo
不是根元素。第二个并不完全符合你的想法 - 它中的命名空间是 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>