2016-05-04 22 views
2

私は、XMLは、この形式で来てい:その属性を持つ要素の値をシリアル化

<run> 
    <foo status="1">111.9</foo> 
    <fred status="0">5.5</fred> 
</run> 
私は以下のこれらの形態のいずれかでこれをデシリアライズしたい

(私は未定だ、と答えを期待しては役立ちます私は#1を好む傾向にあるが、私は何か他のもの)と同じくらいのデザイン美学のために、決定します

ケース#1

[Serializable] 
public class DataValue 
{ 
    [XmlAttribute("status")] 
    public int Status { get; set; } 
    // I need something here, but what? 
    public float Value { get; set; } 
} 
[Serializable] 
[XmlRoot("run")] 
public class DataBag 
{ 
    [XmlElement("foo")] 
    public DataValue Foo{ get; set; } 
    [XmlElement("fred")] 
    public DataValue Fred{ get; set; } 
} 

私はこれをしようとすると、私はどちらかのメンバーfooの0の値を取得またはフレッド。

ケース#2

[Serializable] 
[XmlRoot("run")] 
public class DataBag2 
{ 
    [XmlElement("foo")] 
    public float Foo{ get; set; } 

    [XmlElement("foo")] 
    [XmlAttribute("status")] 
    public int Foo_status { get; set; } 

    [XmlElement("fred")] 
    public float Fred{ get; set; } 

    [XmlElement("fred")] 
    [XmlAttribute("status")] 
    public int Fred_status { get; set; } 
} 

それはコンパイルが、最も内側の例外は非配列タイプの場合、あなたは以下の属性を使用可能」であるためFoo_status、反射しながら私はInvalidOperationExceptionが出る:XmlAttributeを、のXmlText、のXmlElement 、またはXmlAnyElement。 "

ケース#1の場合は実際の値になるか、ケース#2の場合は例外(および有効な値とステータス)になりますか?

直列化のためのコードは次のようになります:あなたの注意のための

// Case 1 
using (var sr = new StreamReader("data.xml")) 
{ 
    var xs = new XmlSerializer(typeof(DataBag)); 
    var run = (DataBag)xs.Deserialize(sr); 
    Console.WriteLine("Got a run: {0}-{1}", run.Fred.Value, run.Fred.Status); 
    // Issue here is that value is always 0, but status is accurate 
} 
// case 2 
using (var sr = new StreamReader("data.xml")) 
{ 
    var xs = new XmlSerializer(typeof(DataBag2));// Exception here 
    var run = (DataBag2)xs.Deserialize(sr); 
    Console.WriteLine("Got a run: {0}-{1}", run.Foo, run.Foo_status); 
} 

感謝を!

答えて

2

あなただけのXMLTEXTとしてそれをマークする必要があります。

[XmlText] 
    public float Value { get; set; } 
+0

グレート回答を!私は今、IXmlSerializableから派生する必要がないシンプルなシリアライズモデルを使用できます。 –

2

あなたは[XmlText]を使用したい:

は、それを含むクラスがシリアライズされたまたは直列化復元されたときにメンバーがXMLテキストとして扱われなければならないことにXmlSerializerに示します。

したがって:あなたが望むよう

public class DataValue 
{ 
    [XmlAttribute("status")] 
    public int Status { get; set; } 
    [XmlText] 
    public float Value { get; set; } 
} 

ケース#2だけでは動作しません。 [XmlAttribute("status")]Foo_statusに追加すると、ではなくFooの属性としてFoo_statusが属性としてシリアル化されることを意味します。 [XmlElement("foo")]を適用すると、DataBag2の要素だと言われています。もちろん、他の属性と競合しています。

入れ子要素に適用される属性を指定する外部コンテナタイプの場合、XmlSerializerの方法はありません。ケース1の場合

関連する問題