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 は正常に逆シリアル化されず、NULL オブジェクトが返されます。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 に答える