0
[XmlRoot("Quote")]
public class Quote
{
    [XmlElement("Insurance")]
    public InsuranceDetails InsDetails { get; set; }
    [XmlElement("Payment")]
    public PaymentDetails PayDetails { get; set; }
}

public class InsuranceDetails : IXmlSerializable
{
    [XmlElement(ElementName = "Details1")]
    public string Details1 { get; set; }

    public void ReadXml(XmlReader reader)
    {
            reader.ReadStartElement("Insurance");
               Details1 = reader.ReadElementString("Details1");
            reader.ReadEndElement();
    }
    public void WriteXml(XmlWriter writer)
    {
        // do write suff
    }
}

public class PaymentDetails
{
    [XmlElement(ElementName = "Details1")]
    public string Details1 { get; set; }
}

鉴于此示例,使用 XmlSerializer 将我的字符串反序列化为 QuoteObject,PaymentDetails 没有成功反序列化,返回一个空对象,因为它似乎应该具有 IXmlDeserializable。它仅在首先解析 PaymentDetails 时才有效。这是 XmlSerializer 的一些预期行为吗?

using (TextReader read = new StringReader(xml))
{
    var serializer = new XmlSerializer(typeof(Quote));
    return (Quote)serializer.Deserialize(read);
}
4

2 回答 2

1

那么这些是我修改ReadXml的:WriteXml

 public void ReadXml(XmlReader reader)
 {
    reader.MoveToContent();
    var empty=reader.IsEmptyElement;
    reader.ReadStartElement();
    if(!empty){
        Details1=reader.ReadElementString("Details1");
        reader.ReadEndElement();
    }
}
public void WriteXml(XmlWriter writer)
{
    var str=string.IsNullOrWhiteSpace(Details1)?"":Details1;            
    writer.WriteElementString("Details1",str);
}

以下是序列化和反序列化函数:

public static string Serialize<T>(T t)
{
    var xmlser=new XmlSerializer(typeof(T));    
    XmlWriterSettings settings = new XmlWriterSettings();

    using(StringWriter textWriter = new StringWriter()) {
        using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
            xmlser.Serialize(xmlWriter, t);
        }
        return textWriter.ToString();
    }
}

public static T Deserialize<T>(string xml) 
{
     if(string.IsNullOrEmpty(xml)) {
        return default(T);
    }

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlReaderSettings settings = new XmlReaderSettings();

    using(StringReader textReader = new StringReader(xml)) {
        using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) {
            return (T) serializer.Deserialize(xmlReader);
        }
    }
}

序列化测试:

var q=new Quote();
q.PayDetails = new PaymentDetails{Details1="Payment Details 1"};
q.InsDetails=new InsuranceDetails{Details1="Insurance Details 1"};  

str = Serialize<Quote>(q);

这给出了(str):

<?xml version="1.0" encoding="utf-16"?>
<Quote xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Payment>
        <Details1>Payment Details 1</Details1>
    </Payment>
    <Insurance>
        <Details1>Insurance Details 1</Details1>
    </Insurance>
</Quote>

反序列化测试:

var dq=Deserialize<Quote>(str);

Console.WriteLine(dq.PaymentDetails.Detail1);//gives "Payment Details 1"
Console.WriteLine(dq.InsuranceDetails.Detail1);//gives "Insurance Details 1"

PS:-序列化代码是从另一个 SO 答案逐字复制的。我学会了如何使用StringWriter.

于 2014-02-24T23:55:21.247 回答
1

首先,您不必IXmlSerializable在任何类中实现。其次,您不提供xml变量的内容。如果您手动创建它,它可能包含错误类型/错误。

我使用以下代码来测试您的类:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace XmlDeSerialize
{
    [XmlRoot("Quote")]
    public class Quote
    {
        [XmlElement("Insurance")]
        public InsuranceDetails InsDetails { get; set; }
        [XmlElement("Payment")]
        public PaymentDetails PayDetails { get; set; }
    }
    public class InsuranceDetails
    {
        [XmlElement(ElementName = "Details1")]
        public string Details1 { get; set; }
    }
    public class PaymentDetails
    {
        [XmlElement(ElementName = "Details1")]
        public string Details1 { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var qin = new Quote
            {
                InsDetails = new InsuranceDetails { Details1 = "insurance details text" },
                PayDetails = new PaymentDetails { Details1 = "payment details text" },
            };

            string xml;
            using (var stream = new MemoryStream())
            {
                var serializer = new XmlSerializer(typeof(Quote));
                serializer.Serialize(stream, qin);
                stream.Position = 0;
                using (var sr = new StreamReader(stream))
                {
                    xml = sr.ReadToEnd();
                }
            }

            Quote qout;
            using (TextReader read = new StringReader(xml))
            {
                var deserializer = new XmlSerializer(typeof(Quote));
                var obj = deserializer.Deserialize(read);
                qout = (Quote)obj;
            }
            Console.WriteLine("InsDetails.Details1='{0}'", qout.InsDetails.Details1);
            Console.WriteLine("PayDetails.Details1='{0}'", qout.PayDetails.Details1);
        }
    }
}

序列化后的值xml

<?xml version="1.0"?>
<Quote xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Insurance>
        <Details1>insurance details text</Details1>
    </Insurance>
    <Payment>
        <Details1>payment details text</Details1>
    </Payment>
</Quote>

我收到的控制台输出:

InsDetails.Details1='insurance details text'
PayDetails.Details1='payment details text'

自己尝试代码,看看它是否适合你。对我来说,显然您没有为反序列化提供有效的 XML 内容,或者您​​没有在问题中提供的代码的其他部分是罪魁祸首。

于 2014-02-25T00:03:40.627 回答