2009-09-24 4 views
0

저는 Microsoft의 .net XmlSerializer를 사용하여 약간의 벽돌 벽을 보았습니다. 나는 하나의 객체를 사용하고 있다면 괜찮은 객체로 일부 XML을 비 직렬화하려고 노력하고있다. 그러나 객체가 List에 객체를 넣고 그것을 직렬화/비 직렬화하려고 할 때 문제가 생긴다. - JezNamespace의 XMLNS이 적용되는 클래스 '푸'는 루트 요소로 직렬화하는 경우C# XmlSerializer를 사용하여 일반 목록을 비 직렬화 할 때의 문제

http://pastebin.com/m22e6e275

이, 일이 잘 작동, 예상대로 : 첫번째로, 여기에 문제를 설명하는 샘플 C# 윈도우 콘솔 프로그램입니다 루트 푸 (Foo) 요소에 전달하면 비 직렬화가 올바르게 수행됩니다. 그러나 목록을 만들고 직렬화하면 XmlSerializer가됩니다. - ArrayOfFoo의 루트 요소를 만듭니다. - Foo 요소를 해당 요소의 자식으로 넣습니다. - Foo의 모든 자식 xmlns를 JezNamespace 네임 스페이스로 설정합니다!

첫 번째 두 개는 정상이지만 세 번째 것은 미친 것 같습니다. 아마도 XmlSerializer의 버그일까요? 이 문제를 해결할 수있는 방법이 있습니까? 나는 Foo의 모든 자식에 대한 네임 스페이스를 지정하고 싶지 않습니다. 단지 Foo에 지정하려고합니다. 그렇게하면 현재 XmlSerializer는 클래스를 올바르게 deserialize하지 않습니다. JezNamespace xmlns가 설정된 임의의 Foo 요소는 건너 뜁니다. 모든 자식 요소를 xmlns로 설정해야합니다.

<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가이 목록에 제대로 그 역 직렬화 할 수있다 : I가 좀하고 싶습니다 무엇

는 XmlSerializer가 같은 것을 생성하는 것입니다. 어떤 생각을 어떻게 할 수 있습니까?

답변

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 유형의 네임 스페이스이다.

이름과 요소의 네임 스페이스를 지정하려면, 대신 (오, 당신은 그 부모 클래스가 필요합니다) 부모 클래스의 List<Foo> 특성에 XmlArrayItemAttribute를 사용할 필요가 않습니다

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 중간 요소, 당신은 XmlElement과 위의 코드에서 XmlArrayItem를 대체 할 수 있음을 원하지 않는 경우. 이 경우 출력 XML은 다음과 같습니다.

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

안녕하세요 Pavel, 유용한 의견을 주셔서 감사합니다. 유일한 문제는 FooParent 클래스를 선언해야한다는 것입니다. 이것은 실제적으로 이것을 필요로하는 프로젝트에서 코드의 리팩토링이 필요합니다 (내 프로그램은 분명히 테스트 케이스였습니다). 'Foo'에 해당하는 것은 반환해야 할 클래스 세트입니다 목록에. FooParent 래퍼 클래스없이이 효과를 얻을 수있는 방법은 없습니까? 대신 List 을 직접 serialize/deserialize 할 수 있습니까? – Jez

+0

나는 어떤 좋은 것을 알지 못합니다.가장 가까운 방법은 CodeDOM 또는 Reflection.Emit을 사용하여 런타임에 해당 래퍼 클래스를 생성하는 것입니다. –

+0

좋습니다, 감사합니다. Microsoft가 XmlSerializer에서이 기능을 제공하지 않았다는 것에 실망했습니다. – Jez

관련 문제