【问题标题】:Serialize an element value with its attributes序列化元素值及其属性
【发布时间】:2016-05-06 00:15:49
【问题描述】:

我有一个以这种形式出现的 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,其中最里面的异常是“对于非数组类型,您可以使用以下属性: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);
}

感谢您的关注!

【问题讨论】:

    标签: c# xml serialization


    【解决方案1】:

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

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

    【讨论】:

    • 很好的答案!我现在可以使用简单的序列化模型,我不必从 IXmlSerializable 派生。
    【解决方案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 无法为外部容器类型指定要应用于嵌套元素的属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-05
      相关资源
      最近更新 更多