2011-02-09 6 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シリアル化を使用する場合は、常にフィールドの値を指定し、一致する "specified"プロパティをtrueに設定する必要があります。あなたはこれにコーディングし、期待通りに動作します

変更:あなたが投稿生成されたクラスで

var myGraph = new graph(); 
myGraph.myString = "hallo"; 
myGraph.myInt = 80; 
myGraph.myIntSpecified = true; 
+0

ええと、私はその分野に気付き、xsd.exeを使って作業すると何度も見ました。私は想像しませんでした、それは "真"に "手動で"設定する必要があります。 – 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の説明は素晴らしいです。もう1つのヒントとして、[CodeDomProvider](http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider.aspx)とXmlSchemaImporterとXmlCodeExporterを使用して、 CodeDOM。その後、生成されたコードをCodeDOMで調整することができます。これにより、必要に応じて、生成されたコードを自由に制御することができます。 –

関連する問題