Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[Sérialisation XML][C#] préserver les balises du contenu

4 réponses
Avatar
fragmonster
Bonjour,
J'ai un petit souci avec la s=E9rialisation XML. J'ai une classe que
j'instancie puis que j'initialise avec du contenu provenant de ma base
de donn=E9es. Pour donner un exemple simplifi=E9 je souhaite obtenir le
r=E9sultat suivant:

Code:
<Fiche>
<Titre>Titre exemple</Titre>
<Texte>Ceci est le <b>Texte de l'exemple</b></Texte>
</fiche>


Donc ma classe se nomme Fiche et poss=E8de deux membres "titre" et
"texte" de type string. Jusque l=E0 pas de souci.

Comme vous pouvez le voir, dans ma base de donn=E9es, j'ai du contenu
qui poss=E8de qques enrichissements html. Dans l'exemple on voit
<b>...</b>

Or, quand je s=E9rialise ma classe, toutes les balises du contenu sont
transform=E9es comme suit :

Code:
<Fiche>
<Titre>Titre exemple</Titre>
<Texte>Ceci est le &lt;b&gt;Texte de l'exemple&lt;/b&gt;</Texte>
</fiche>


Et lors de la fusion avec ma feuille XSLT ces balises ne sont pas
interpr=E9t=E9es

Comment faire pour pr=E9server les balises provenant de la base lors de
la s=E9rialisation?

Merci

4 réponses

Avatar
Patrick Philippot
Bonjour,

Nous avons traité un problème équivalent dans le fil "transformation XML
en HTML" de ce groupe .

Les données contenant de l'HTML doivent être encadrées par une balise
CDATA. Lors de la transformation XSL, récupérez le contenu de la balise
CDATA mais surtout, n'utilisez pas un XmlTextWriter pour écrire le
fichier mais un FileStream. Raisons expliquées dans le thread mentionné
ci-dessus.

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
fragmonster
Merci, c'est intéressant. Mais mon problème est un peu différent car
le fichier XML est lui même généré par le programme en sérialisant
mon object fiche :

class Fiche{
protected string titre;
protected string texte;

public Fiche(string titre, string texte){
this.titre = titre;
this.texte = "<![CDATA["+texte+"]]>";
}

private void SerializeFiche(string filename){
XmlSerializer x = new XmlSerializer(typeof(Fiche));
TextWriter writer = new StreamWriter(filename);
x.Serialize(writer, this);
writer.Close();
}
}

Mon problème est que même si j'encapsule le texte dans un CDATA,
celui ci sera aussi traduit en &gt; ...Etc

Peut-être devraije essayer autre chose qu'un TextWriter?
Avatar
Patrick Philippot
fragmonster wrote:
Mon problème est que même si j'encapsule le texte dans un CDATA,
celui ci sera aussi traduit en &gt; ...Etc



Dans ce cas, je crains que vous ne soyez obligé soit d'implémenter
l'interface ISerializable dans votre classe, soit de sérialiser
vous-même à partir d'un XmlDocument dans lequel vous aurez créé des
XmlCDataSection. Le mécanisme de sérialisation automatique ne semble pas
supporter les sections CData et je ne vois aucun attribut permettant de
gérer cela.

Comme par ailleurs vous passez, si j'ai tout compris, par une phase de
sérialisation sur le disque pour ensuite appliquer une transformation
XSL sur le résultat pour produire un autre fichier, il serait de toutes
façons plus performant de créer le XmlDocument document en mémoire et
d'appliquer la transformation XSL dessus directement. Juste une
suggestion...

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr
Avatar
Patrick Philippot
Bonkour,

fragmonster wrote:
Merci, c'est intéressant. Mais mon problème est un peu différent car
le fichier XML est lui même généré par le programme en sérialisant
mon object fiche :



Après discussion avec un collègue MVP, je vous confirme que le seul
moyen de régler le problème est d'implémenter l'interface
IXmlSerializable. Ce n'est pas incroyablement compliqué. Voici un
exemple:

Classe représentant un membre à sérialiser en CDATA

#region Classe MonCDataItem
public class MonCDataItem: IXmlSerializable
{
public string Value;
#region IXmlSerializable Members

public void WriteXml(XmlWriter writer)
{
writer.WriteCData(Value);
}

public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}

public void ReadXml(XmlReader reader)
{
reader.Read();
if ( reader.NodeType == XmlNodeType.CDATA )
Value = reader.ReadString();
}
#endregion
}
#endregion

Classe à sérialiser:

[XmlRoot("Item")]
public class WOItem: _CollectionItemBase
{
[XmlAttribute] public int ConcurrencyID;
[XmlAttribute] public int TypeID;
[XmlAttribute] public int Index;
[XmlAttribute] public int OriginalWorkOrderID;
[XmlAttribute] public int GroupID;
[XmlAttribute] public int StatusID;
[XmlAttribute] public string Status;
[XmlAttribute] public string Done;
[XmlAttribute] public int W;
[XmlElement] public Task Task;
[XmlElement] public Asset Asset;
[XmlElement] public MonCDataItem MonItem;
// L'élément à sérialiser en CDATA
}

--
Patrick Philippot - Microsoft MVP
MainSoft Consulting Services
www.mainsoft.fr