2009-09-09 4 views
6

ich Probleme habe einen CDATA-Abschnitt Serialisierung # mit cXML-Serialisierung - XmlCDataSection als Serialization.XmlText

Ich brauche XmlCDataSection Objekteigenschaft als Innertext des Elements serialisiert.

Das Ergebnis ich suche das ist:

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

Um dies zu produzieren, ich bin mit diesem Objekt:

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

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

Wenn die xmltext Anmerkung über den Wert Eigenschaft mit dem folgenden Fehler geworfen.

System.InvalidOperationException: Es gab einen Fehler reflektierende Eigenschaft 'Wert'. ---> System.InvalidOperationException: Serialisierung Member 'Wert' von Typ System.Xml.XmlCDataSection. XmlAttribute/XmlText nicht zu kodieren komplexen Typen verwendet wird

Wenn ich die Anmerkung auf Kommentar, wird die Serialisierung, aber die Meldung CDATA-Abschnitt wird in einen Wert Element gelegt, die für nicht gut ist, was ich zu tun versuchen, :

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

Kann mir jemand in die richtige Richtung, um dies zur Arbeit zu bringen.

Danke, Adam

+0

Was passiert, wenn Sie '[XmlText]' entfernen geschieht? –

Antwort

5

Danke Richard, hatte erst jetzt die Chance, darauf zurückzukommen. Ich denke, ich habe das Problem gelöst, indem ich Ihren Vorschlag verwendet habe. Ich habe ein CDataField-Objekt mit dem folgenden erstellt:

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"); 
     } 
    } 
+0

es wirft 'A.CDataField kann nicht serialisiert werden, da es keinen parameterlosen Konstruktorfehler hat – tchelidze

2

Die Art und Weise Test definiert ist, ist Ihre Daten ein CData Objekt. Das Serialisierungssystem versucht also, das CData-Objekt zu erhalten.

Sie möchten jedoch einige Textdaten als CData-Abschnitt serialisieren. Der erste Typ Test.value sollte String sein.

Sie müssen dann steuern, wie dieses Feld serialisiert wird, aber es scheint keine eingebaute Methode oder ein eingebautes Attribut zu geben, um zu steuern, wie Strings serialisiert werden (als String, möglicherweise mit Entitäten für reservierte Zeichen oder als CDATA). (Da XML-Infoset alle diese sind die gleichen, ist dies nicht überraschend.)

Sie können natürlich implementiert IXmlSerializable und einfach die Serialisierung der Test Art selbst, die Ihnen die vollständige Kontrolle gibt.

0

Ich hatte sehr dasselbe Problem wie Adam. Allerdings hilft mir diese Antwort nicht zu 100% :) gibt mir aber einen Hinweis. Also habe ich einen Code wie unten erstellt.Es erzeugt XML wie folgt aus:

<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> 

Code:

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; } 
} 
1

nur eine Alternative aus here gefunden:

 [XmlIgnore] 
      public string Content { get; set; } 

    [XmlText] 
      public XmlNode[] CDataContent 
      { 
       get 
       { 
        var dummy = new XmlDocument(); 
        return new XmlNode[] {dummy.CreateCDataSection(Content)}; 
       } 
       set 
       { 
        if (value == null) 
        { 
         Content = null; 
         return; 
        } 

        if (value.Length != 1) 
        { 
         throw new InvalidOperationException(
          String.Format(
           "Invalid array length {0}", value.Length)); 
        } 

        var node0 = value[0]; 
        var cdata = node0 as XmlCDataSection; 
        if (cdata == null) 
        { 
         throw new InvalidOperationException(
          String.Format(
           "Invalid node type {0}", node0.NodeType)); 
        } 

        Content = cdata.Data; 
       } 
      } 
     } 
Verwandte Themen