5

Ipotizzando un XML come questo:valore dell'elemento Deserialize come stringa anche se contiene contenuto misto

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex> 
     <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
      <div><h1>content</h1></div> 
     </html> 
    </my:FieldComplex> 
<my:Root> 

e una classe come:

[Serializable] 
[XmlType(AnonymousType = true, Namespace = "http://foo/bar")] 
[XmlRoot(ElementName = "Root", Namespace = "http://foo/bar", IsNullable = false)] 
public class MyRoot 
{ 
    public string FieldBasic { get; set; } 
    public string FieldComplex { get; set; } 
} 

Come faccio a deserializzare <my:FieldComplex> ad una stringa all'interno FieldComplex? Non riesce quando trova l'HTML all'interno. Voglio fare mi dà una stringa con questo contenuto:

<html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
    <div><h1>content</h1></div> 
</html> 

Se io dichiaro FieldComplex come public object FieldComplex (vale a dire xsd:anyType) funziona un pò e ho un XMLNode[] all'interno del quale posso usare.

ma ho bisogno del FieldComplex essere di tipo stringa per la serializzazione come per la serializzazione XML non conterrà HTML, sarà come:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex>content</my:FieldComplex> 
<my:Root> 

Dichiarare FieldComplex come oggetto inserirà questi attributi sul <my:FieldComplex> Elemento:

xmlns:q1="http://www.w3.org/2001/XMLSchema" p3:type="q1:string" xmlns:p3="http://www.w3.org/2001/XMLSchema-instance 

e io non voglio quello. Inoltre, non desidero utilizzare classi diverse per la serializzazione e la deserializzazione.

Quindi, è possibile?

per fare una lunga storia breve, è possibile avere questa classe:

public class MyRoot 
{ 
    public string FieldBasic { get; set; } 
    public string FielComplex { get; set; } 
} 

Serialize a questo:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex>content</my:FieldComplex> 
<my:Root> 

e deserializzare da questo:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex> 
     <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
      <div><h1>content</h1></div> 
     </html> 
    </my:FieldComplex> 
<my:Root> 

?

P.S. Giusto per spiegare "il perché?". Ho una strega di classe che viene serializzata. L'XML serializzato attraversa quindi più nodi nell'applicazione e alla fine ritorna ma viene modificato come sopra. I layer eseguono alcune convalide XML e gli attributi o gli elementi aggiuntivi in ​​ingresso non superano la convalida e interrompono il flusso. Voglio mappare il codice XML di ritorno alla stessa classe. Il contenuto è solo stringhe da esso il proprio punto di vista, ma, naturalmente, non è la stessa per la serializzazione/deserializzazione :(

risposta

3

Questo non è ancora finito perché non riesco a ricordare se è possibile/come aggiungere il prefisso dello spazio dei nomi all'elemento root in Serialization Xml.Ma se si implementa l'interfaccia IXmlSerializable nella tua classe myRoot come questo:

[XmlRoot("Root", Namespace="http://foo/bar")] 
public class MyRoot : IXmlSerializable 

quindi scrivere i metodi di serializzazione XML te stesso, qualcosa di simile:

 void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) 
     { 
      reader.MoveToContent(); 
      var outerXml = reader.ReadOuterXml(); 
      XElement root = XElement.Parse(outerXml); 

      this.FieldBasic = root.Elements(XName.Get("FieldBasic", "http://foo/bar")).First().Value; 
      this.FieldComplex = root.Elements(XName.Get("FieldComplex", "http://foo/bar")).First().Elements().First().Value.Trim(); 
     } 



     void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) 
     { 
      writer.WriteRaw(String.Format("\r\n\t<my:FieldBasic>\r\n\t\t{0}\r\n\t</my:FieldBasic>", this.FieldBasic)); 
      writer.WriteRaw(String.Format("\r\n\t<my:FieldComplex>\r\n\t\t{0}\r\n\t</my:FieldComplex>\r\n", this.FieldComplex)); 
     } 

(restituire null dal metodo GetSchema)

Questo dovrebbe farti almeno abbastanza vicino a quello che stai cercando.

Potresti anche trovare questi link utili.

IXmlSerializable

Namespaces

+0

Grazie mille per questa soluzione :). Questo e 'esattamente quello che stavo cercando. – Beniamin

3

è possibile utilizzare CDATA in XML per indicare che il contenuto è una stringa letterale:

<my:Root xmlns:my="http://foo/bar"> 
    <my:FieldBasic>content</my:FieldBasic> 
    <my:FieldComplex> 
    <![CDATA[ 
     <html xml:space="preserve" xmlns="http://www.w3.org/1999/xhtml"> 
     <div><h1>content</h1></div> 
     </html> 
    ]]> 
    </my:FieldComplex> 
</my:Root> 
+1

Purtroppo ho il controllo solo su ciò che entra nel flusso, non ciò che esce. Non riesco ad aggiungere il . – JohnDoDo