使用其属性序列化元素值

时间:2016-05-04 21:42:27

标签: c# xml serialization

我有一个以这种形式出现的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或fred成员的值为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,其中最内层的异常是&#34;对于非数组类型,您可以使用以下属性:XmlAttribute,XmlText,XmlElement或XmlAnyElement。&#34;

在案例#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 个答案:

答案 0 :(得分:2)

您想使用[XmlText]

  

向XmlSerializer指示当包含成员的类被序列化或反序列化时,该成员必须被视为XML文本。

因此:

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

案例#2根本无法正常工作。将[XmlAttribute("status")]添加到Foo_status意味着Foo_status将被序列化为DataBag2的属性,而不是Foo。同时应用[XmlElement("foo")]然后说它是DataBag2的元素,当然这与其他属性相冲突。

外部容器类型XmlSerializer无法指定要应用于嵌套元素的属性。

答案 1 :(得分:2)

对于案例1,您只需将其标记为XMLText:

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