2011-02-09 2 views
1

내 문제는 매우 이상하게 보였으므로 그 문제는 다른 것으로 생각되지 않았으므로 매우 간단하고 어리석은 실수 인 것 같습니다. 찾아내는 것.C# XmlSerializer는 xs : attribute를 xs : string이 아닌 다른 형식으로 무시합니다.

xsd.exe를 사용하여 클래스 구조를 생성하는 XSD가 있습니다. 내 객체를 값으로 채 웁니다. 그러나 XML에 직렬화 할 때 유형이 string이 아닌 모든 클래스 속성은 무시됩니다.

var myGraph = new graph(); 
myGraph.myString = "hallo"; 
myGraph.myInt = 80; 

var serializer = new XmlSerializer(typeof(graph)); 
TextWriter writeFileStream = new StreamWriter(Path.Combine(outFolder, outFile)); 
serializer.Serialize(writeFileStream, myGraph); 
writeFileStream.Close(); 

내가 예상 :

<graph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    myString="hallo" 
    myInt="80" 
/> 

실제 출력은 다음과 같습니다

<graph xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    myString="hallo" 
/> 

이 속성 myInt이 무시되었습니다. 문자열로 정의하면 표시되지만 다른 형식으로는 표시되지 않습니다. 내가 required이라고 선언하고 null으로두면 myInt="0"으로 직렬화됩니다.

무엇이 누락 되었습니까?

일부 세부 정보 :

XSD :

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="graph"> 
    <xs:complexType> 
     <xs:attribute name="myString" type="xs:string" /> 
     <xs:attribute name="myInt" type="xs:int" /> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

생성 된 클래스 : 귀하의 측면 내 친구에가는 다른

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=false)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)] 
public partial class graph { 
    private string myStringField; 
    private int myIntField; 

    [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified)] 
    public string myString { 
     get { return this.myStringField; } 
     set { this.myStringField = value; } 
    } 

    [System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified)] 
    public int myInt { 
     get { return this.myIntField; } 
     set { this.myIntField = value; } 
    } 

    [System.Xml.Serialization.XmlIgnoreAttribute()] 
    public bool myIntSpecified { 
     get { return this.myIntFieldSpecified; } 
     set { this.myIntFieldSpecified = value; } 
    } 
+0

에서, myIntSpecified 기능은 myIntFieldSpecified 변수를 참조하지만, 내가 수업 시간에 어디서든 정의 된이 변수가 표시되지 않습니다 ? – pmartin

답변

7

XSD는 값 유형 인 모든 등록 정보에 대해 추가로 "지정된"필드를 추가합니다. 값 형식이있는 .NET serialization을 사용하는 경우 항상 필드 값을 지정하고 일치하는 "specified"속성을 true로 설정해야합니다. 이것에

은 변경하면 코드를 그것은 예상대로 작동합니다

당신이 게시 생성 된 클래스에서
var myGraph = new graph(); 
myGraph.myString = "hallo"; 
myGraph.myInt = 80; 
myGraph.myIntSpecified = true; 
+0

흠, xsd.exe로 작업 할 때 필자는 그 필드를 여러 번 보았습니다. 나는 단지 상상하지 못했다. 그것은 수동으로 "true"로 설정되어야한다. – Jan

+0

이 힌트를 많이 주셔서 감사합니다. 나는이 버그에 대해 미쳐 가고있었습니다. 내 상사는 "이것은 제 1 장입니다 - 당신은 그것을 알아야합니다"라고 말할 것입니다. 감사! – Jan

0

가 뭔가. 나는 코드를 컴파일했고, 그것은 완벽하게 작동 :

클래스 :

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = false)] 
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 
public partial class graph 
{ 
    private string myStringField; 
    private int myIntField; 

    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)] 
    public string myString 
    { 
     get { return this.myStringField; } 
     set { this.myStringField = value; } 
    } 

    [System.Xml.Serialization.XmlAttributeAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)] 
    public int myInt 
    { 
     get { return this.myIntField; } 
     set { this.myIntField = value; } 
    } 


} 

코드 :

graph g = new graph() {myInt = 80, myString = "ali"}; 
    XmlSerializer xss = new XmlSerializer(typeof (graph)); 
    MemoryStream ms = new MemoryStream(); 
    xss.Serialize(ms, g); 
    StreamReader sb = new StreamReader(ms); 
    ms.Position = 0; 
    Console.WriteLine(sb.ReadToEnd()); 

출력이 확실

<graph xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org 
/2001/XMLSchema-instance" myString="ali" myInt="80" /> 
+0

생성 된 코드가 자신과 다른 것으로 보입니다. –

+0

나는 생성하지 않았다. 나는 그에게서 클래스를 복사하고 간단한 테스트 장치를 썼다. – Aliostad

+0

@Aliostad - 수업 (위에 게시 한 내용 이상)이 원래 게시물의 생성 된 수업과 다릅니다.게시 한 클래스의 myIntSpecified 필드가 누락되었습니다. – pmartin

2

난 100 % , 그러나 비슷한 것을 기억하십시오. 생성 된 'myIntSpecified'필드를 확인 하시겠습니까? 이것을 true로 설정해야합니다.

xsd.exe에는 몇 가지 큰 한계가 있습니다. 대체로 google을 사용하거나 매번 true로 설정하는 것을 기억하십시오. :)

+0

글쎄, 나는'xsd.exe' 대신에'svcutil.exe'를 사용했지만'xs : attributes'를 사용하는 데 많은 어려움을 겪었고'xsd.exe'는 그 사건. 다른 경우에는 여전히'svcutil.exe'를 고집합니다. 답장을 보내 주셔서 감사합니다. 평판 포인트가 더 많은 경우 투표 해 드리겠습니다. – Jan

+2

@Nylle : 문제 없습니다. @ pmartin의 설명이 좋습니다. 한 가지 더 팁은 [CodeDomProvider] (http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.aspx)와 XmlSchemaImporter 및 XmlCodeExporter를 사용하여 CodeDOM. 그런 다음 CodeDOM을 통해 생성 된 코드를 조정할 수 있습니다. 원하는 경우 생성 된 코드를 추가로 제어 할 수 있습니다. –

관련 문제