简体   繁体   English

从.NET将类型序列化为XML

[英]Serialize type into XML from .NET

I have this C# 4.0 type 我有这个C#4.0类型

public class DecimalField
{
    public decimal Value { get; set; }
    public bool Estimate { get; set; }
}

I want to use XmlSerializer to serialize the type into 我想使用XmlSerializer将类型序列化为

<Val Estimate="true">123</Val>

Ideally, I want to omit the Estimate attribute if its value is false. 理想情况下,如果其值为false,我想省略Estimate属性。 Changing Estimate to a nullable bool is acceptable. 将估计值更改为可以为空的bool是可以接受的。

What attributes/implementations are required to go from this type to this XML representation? 从此类型到此XML表示需要哪些属性/实现?

Thanks. 谢谢。

Not sure if you can output Estimate conditionally with attributes only. 不确定是否可以仅使用属性有条件地输出Estimate。 But you definitelly can implement IXmlSerializable and check Estimate value inside WriteXml method. 但是你definitelly可以实现IXmlSerializable并检查WriteXml方法中的Estimate值。

Here is an example 这是一个例子

Conditionally omitting Estimate would require a lof of coding. 有条件地省略Estimate将需要自我编码。 I wouldn't go that way. 我不会这样。

XmlWriter writer = XmlWriter.Create(stream, new XmlWriterSettings() { OmitXmlDeclaration = true });

var ns = new XmlSerializerNamespaces();
ns.Add("", "");

XmlSerializer xml = new XmlSerializer(typeof(DecimalField));

xml.Serialize(writer, obj, ns);

- -

[XmlRoot("Val")]
public class DecimalField
{
    [XmlText]
    public decimal Value { get; set; }
    [XmlAttribute]
    public bool Estimate { get; set; }
}

You can also manually serialize your class using Linq2Xml 您也可以使用Linq2Xml手动序列化您的类

List<XObject> list = new List<XObject>();
list.Add(new XText(obj.Value.ToString()));
if (obj.Estimate) list.Add(new XAttribute("Estimate", obj.Estimate));

XElement xElem = new XElement("Val", list.ToArray());

xElem.Save(stream);

This is about as close as you can get (an Estimate attribute is always included) without implementing IXmlSerializable: 这是尽可能接近(不包括Estimate属性)而不实现IXmlSerializable:

[XmlRoot("Val")]
public class DecimalField
{
    [XmlText()]
    public decimal Value { get; set; }
    [XmlAttribute("Estimate")]
    public bool Estimate { get; set; }
}

With IXmlSerializable, your class looks like this: 使用IXmlSerializable,您的类看起来像这样:

[XmlRoot("Val")]
public class DecimalField : IXmlSerializable
{
    public decimal Value { get; set; }
    public bool Estimate { get; set; }

    public void WriteXml(XmlWriter writer)
    {
        if (Estimate == true)
        {
            writer.WriteAttributeString("Estimate", Estimate.ToString());
        }

        writer.WriteString(Value.ToString());
    }

    public void ReadXml(XmlReader reader)
    {
        if (reader.MoveToAttribute("Estimate") && reader.ReadAttributeValue())
        {
            Estimate = bool.Parse(reader.Value);
        }
        else
        {
            Estimate = false;
        }

        reader.MoveToElement();
        Value = reader.ReadElementContentAsDecimal();
    }

    public XmlSchema GetSchema()
    {
        return null;
    }
}

You can test your class like this: 您可以像这样测试您的课程:

    XmlSerializer xs = new XmlSerializer(typeof(DecimalField));

    string serializedXml = null;
    using (StringWriter sw = new StringWriter())
    {
        DecimalField df = new DecimalField() { Value = 12.0M, Estimate = false };
        xs.Serialize(sw, df);
        serializedXml = sw.ToString();
    }

    Console.WriteLine(serializedXml);

    using (StringReader sr = new StringReader(serializedXml))
    {
        DecimalField df = (DecimalField)xs.Deserialize(sr);

        Console.WriteLine(df.Estimate);
        Console.WriteLine(df.Value);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM