[Sérialisation XML][C#] préserver les balises du contenu
4 réponses
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 <b>Texte de l'exemple</b></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?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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
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
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
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;
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 > ...Etc
Peut-être devraije essayer autre chose qu'un TextWriter?
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;
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;
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 > ...Etc
Peut-être devraije essayer autre chose qu'un TextWriter?
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 > ...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
fragmonster wrote:
Mon problème est que même si j'encapsule le texte dans un CDATA,
celui ci sera aussi traduit en > ...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
Mon problème est que même si j'encapsule le texte dans un CDATA, celui ci sera aussi traduit en > ...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
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
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
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