8

c# を使用して cdata セクションをシリアル化する際に問題が発生しています

XmlCDataSection オブジェクト プロパティを要素の内部テキストとしてシリアル化する必要があります。

私が探している結果はこれです:

<Test value2="Another Test">
  <![CDATA[<p>hello world</p>]]>
</Test>

これを生成するために、私はこのオブジェクトを使用しています:

public class Test
{
    [System.Xml.Serialization.XmlText()]
    public XmlCDataSection value { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string value2 { get; set; }
}

value プロパティで xmltext 注釈を使用すると、次のエラーがスローされます。

System.InvalidOperationException: プロパティ '値' を反映するエラーが発生しました。---> System.InvalidOperationException: System.Xml.XmlCDataSection 型のメンバー '値' をシリアル化できません。XmlAttribute/XmlText を使用して複合型をエンコードすることはできません

注釈をコメントアウトすると、シリアライゼーションは機能しますが、cdata セクションが値要素に配置されます。これは、私がやろうとしていることには適していません。

<Test value2="Another Test">
  <value><![CDATA[<p>hello world</p>]]></value>
</Test>

これを機能させるための正しい方向に誰かが私を向けることができますか?

ありがとう、アダム

4

5 に答える 5

5

リチャードに感謝します、今だけこれに戻る機会がありました。私はあなたの提案を使って問題を解決したと思います。以下を使用してCDataFieldオブジェクトを作成しました。

public class CDataField : IXmlSerializable
    {
        private string elementName;
        private string elementValue;

        public CDataField(string elementName, string elementValue)
        {
            this.elementName = elementName;
            this.elementValue = elementValue;
        }

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void WriteXml(XmlWriter w)
        {
            w.WriteStartElement(this.elementName);
            w.WriteCData(this.elementValue);
            w.WriteEndElement();
        }

        public void ReadXml(XmlReader r)
        {                      
            throw new NotImplementedException("This method has not been implemented");
        }
    }
于 2009-10-22T13:27:06.937 に答える
2

方法Testが定義されており、データは CData オブジェクトです。そのため、シリアル化システムは CData オブジェクトを保持しようとしています。

しかし、一部のテキスト データを CData セクションとしてシリアル化したい場合があります。

したがって、最初に の型はTest.valueString である必要があります。

次に、そのフィールドのシリアル化方法を制御する必要がありますが、文字列のシリアル化方法を制御する組み込みのメソッドや属性はないようです (文字列として、おそらく予約文字のエンティティを使用して、または CDATA として)。(XML 情報セットの観点からは、これらはすべて同じであるため、これは驚くべきことではありません。)

もちろん、IXmlSerializable を実装して、Test完全に制御できる型のシリアル化を自分でコーディングすることもできます。

于 2009-09-09T11:43:22.647 に答える
0

私はアダムとまったく同じ問題を抱えていました。ただし、この回答は100%役に立ちません:)が、手がかりを与えてくれます。だから私は以下のようなコードを作成しました。次のような XML を生成します。

<Actions>
    <Action Type="reset">
      <![CDATA[
      <dbname>longcall</dbname>
      <ontimeout>
       <url>http://[IPPS_ADDRESS]/</url>
       <timeout>10</timeout>
      </ontimeout>
      ]]>
    </Action>
    <Action Type="load">
      <![CDATA[
      <dbname>longcall</dbname>
      ]]>
    </Action>
</Actions>

コード:

public class ActionsCDataField : IXmlSerializable
{
    public List<Action> Actions { get; set; }

    public ActionsCDataField()
    {
        Actions = new List<Action>();
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void WriteXml(XmlWriter w)
    {
        foreach (var item in Actions)
        {
            w.WriteStartElement("Action");
            w.WriteAttributeString("Type", item.Type);
            w.WriteCData(item.InnerText);                
            w.WriteEndElement();
            w.WriteString("\r\n");
        }
    }

    public void ReadXml(XmlReader r)
    {
        XmlDocument xDoc = new XmlDocument();
        xDoc.Load(r);

        XmlNodeList nodes = xDoc.GetElementsByTagName("Action");
        if (nodes != null && nodes.Count > 0)
        {
            foreach (XmlElement node in nodes)
            {
                Action a = new Action();
                a.Type = node.GetAttribute("Type");
                a.InnerText = node.InnerXml;
                if (a.InnerText != null && a.InnerText.StartsWith("<![CDATA[") && a.InnerText.EndsWith("]]>"))
                    a.InnerText = a.InnerText.Substring("<![CDATA[".Length, a.InnerText.Length - "<![CDATA[]]>".Length);

                Actions.Add(a);
            }
        }
    }
}

public class Action
{
    public String Type { get; set; }
    public String InnerText { get; set; }
}
于 2014-01-27T09:42:10.510 に答える