6

標準の .Net XmlSerializer を使用した CDATA デシリアライゼーションに問題があります。

更新: 外部システムから XML を取得しましたが、その形式に影響を与えることができないため、CData を属性の別の要素に含めることはできません。

シリアル化すると、次のようになります。

<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><![CDATA[Hello, world!]]></MyClass>

逆シリアル化は、オブジェクトを元の状態に復元しません。

シリアル化されているクラスは次のとおりです。

public class MyClass
{
    string _data;

    [XmlIgnore]
    public string Data
    {
        get { return _data; }
        set { _data = value; }
    }

    [XmlAnyElement]
    public XmlCDataSection CData
    {
        get { return new XmlDataDocument().CreateCDataSection(Data); }
        set { Data = value.Value; }
    }
}

失敗するテストは次のとおりです。

[Test]
public void CData_as_inner_text_test()
{
    MyClass item = new MyClass();

    item.Data = "Hello, world!";

    XmlSerializer serializer = new XmlSerializer(item.GetType());
    string serialized;

    using (StringWriter sw = new StringWriter())
    {
        serializer.Serialize(sw, item);
        serialized = sw.GetStringBuilder().ToString();
    }

    MyClass deserialized;

    using (StringReader sr = new StringReader(serialized))
    {
        deserialized = (MyClass)serializer.Deserialize(sr);
    }

    Assert.AreEqual(item.Data, deserialized.Data); // For some reason, deserialized.Data == null
}

ここで同じ問題を見つけましたが、答えはありません: XmlSerializer、XmlAnyElement、および CDATA

4

2 に答える 2

10

CDATA セクションのコンテンツが無視される Data プロパティで終了するため、CData プロパティは null になります...

<MyClass><![CDATA[Hello, world!]]></MyClass>

は以下と完全に同等です:

<MyClass>Hello, world!</MyClass>

外部アプリが MyClass のコンテンツを CData として書き込むかどうかは気にする必要はありません。同様に、外部アプリは、あなたがそれをどのように書き出すかを気にするべきではありません。

IOW、必要なのはこれだけです。

public class MyClass
{
    string _data;

    [XmlText]
    public string Data
    {
        get { return _data; }
        set { _data = value; }
    }
}
于 2008-12-29T10:35:31.687 に答える
0

最初にプロパティをXmlCDataSectionとして宣言します

public XmlCDataSection ProjectXml { get; set; }

この場合、projectXmlは文字列xmlです

ProjectXml = new XmlDocument().CreateCDataSection(projectXml);

あなたがあなたのメッセージをシリアル化するとき、あなたはあなたの素晴らしいフォーマットを持っているでしょう(注意)

<?xml version="1.0" encoding="utf-16"?>
<MessageBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Message_ProjectStatusChanged">
  <ID>131</ID>
  <HandlerName>Plugin</HandlerName>
  <NumRetries>0</NumRetries>
  <TriggerXml><![CDATA[<?xml version="1.0" encoding="utf-8"?><TmData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="9.0.0" Date="2012-01-31T15:46:02.6003105" Format="1" AppVersion="10.2.0" Culture="en-US" UserID="0" UserRole=""><PROJECT></PROJECT></TmData>]]></TriggerXml>
  <MessageCreatedDate>2012-01-31T20:28:52.4843092Z</MessageCreatedDate>
  <MessageStatus>0</MessageStatus>
  <ProjectId>0</ProjectId>
  <UserGUID>8CDF581E44F54E8BAD60A4FAA8418070</UserGUID>
  <ProjectGUID>5E82456F42DC46DEBA07F114F647E969</ProjectGUID>
  <PriorStatus>0</PriorStatus>
  <NewStatus>3</NewStatus>
  <ActionDate>0001-01-01T00:00:00</ActionDate>
</MessageBase>
于 2012-01-31T21:01:12.087 に答える