2009-07-13 9 views
4

J'utilise SyndicationFeed de .NET pour créer des flux RSS et ATOM. Malheureusement, j'ai besoin de contenu HTML dans l'élément description (la propriété Content de SyndicationItem) et le formateur code automatiquement le HTML, mais je préfère que l'élément de description entier soit enveloppé dans CDATA sans coder le code HTML.SyndicationFeed: Contenu en tant que CDATA?

Mon (simple) Code:

var feed = new SyndicationFeed("Title", "Description", 
       new Uri("http://someuri.com")); 
var items = new List<SyndicationItem>(); 

var item = new SyndicationItem("Item Title", (string)null, 
       new Uri("http://someitemuri.com")); 

item.Content = SyndicationContent.CreateHtmlContent("<b>Item Content</b>"); 

items.Add(item); 
feed.Items = items; 

Quelqu'un une idée comment je peux le faire en utilisant SyndicationFeed? Mon dernier recours est de créer "manuellement" le XML pour les flux, mais je préfère utiliser le SyndicationFeed intégré.

Répondre

7

Cela a fonctionné pour moi:

public class CDataSyndicationContent : TextSyndicationContent 
{ 
    public CDataSyndicationContent(TextSyndicationContent content) 
     : base(content) 
    {} 

    protected override void WriteContentsTo(System.Xml.XmlWriter writer) 
    { 
     writer.WriteCData(Text); 
    } 
} 

vous pouvez:

new CDataSyndicationContent(new TextSyndicationContent(content, TextSyndicationContentKind.Html)) 
+0

Cela a également fonctionné pour moi. – thelsdj

+0

Grande solution, juste ce que je cherchais. –

+7

J'ai essayé de faire la même chose - nouveau CDataSyndicationContent (nouveau TextSyndicationContent ("

" + d.Description, TextSyndicationContentKind.Html)); mais il encode toujours le code HTML? Lors du suivi du code, WriteContentsTo n'est jamais appelé. – TimLeung

-2

essayer

item.Content = "<![CDATA[" + 
      SyndicationContent.CreateHtmlContent("<b>Item Content</b>") + "]]>"; 
+0

thx, mais ne fonctionne pas (erreur de compilation), car item.Content nécessite un objet SyndicationContent. L'autre façon est également ne fonctionne pas autour, le contenu, y compris les CDATA-tags est codé: "<[+ "élément de contenu" + « ] item.Content = SyndicationContent.CreateHtmlContent (! CDATA ["]>) "; –

3

Cela devrait fonctionner.

item.Content = new TextSyndicationContent("<b>Item Content</b>",TextSyndicationContentKind.Html); 
+0

SyndicationContent.CreateHtmlContent() encapsule ce qui suit afin que le résultat soit le même quel que soit votre usage. Je crois que le problème se pose lorsque vous essayez d'écrire le flux sur le XmlWriter. –

1

essayer cette

XmlReaderSettings settings = new XmlReaderSettings(); 
      settings.IgnoreComments = false; 
      //settings.ProhibitDtd = false; 
      using (XmlReader reader = XmlReader.Create(rssurl, settings)) 
2

j'ai eu le même problème que certains où le remplacement de WriteContentsTo n'a pas été appelé dans l'exemple cpowers (toujours pas d'identifiant ea pourquoi). Donc, je l'ai changé pour hériter de la classe SyndicationContent à la place. Je ne sais pas si c'est la meilleure solution, mais a bien fonctionné dans ma situation.

public class CDataSyndicationContent : SyndicationContent 
{ 
    public CDataSyndicationContent(string content) 
    { 
     Text = content; 
    } 

    public override SyndicationContent Clone() 
    { 
     return new CDataSyndicationContent(Text); 
    } 

    public override string Type 
    { 
     get { return "html"; } 
    } 

    public string Text { get; private set; } 

    protected override void WriteContentsTo(XmlWriter writer) 
    { 
     writer.WriteCData(Text); 
    } 
} 
+0

Il semblerait que la fonctionnalité soit différente selon les versions de .NET, mais cette solution par @WonderGrub l'a corrigé pour moi sur .NET 4.0. Pour définir le contenu, utilisez simplement: 'item.Content = new CDataSyndicationContent (" Item Content ")' – icewhite

3

Pour ceux pour qui la solution fournie par cpowers et WonderGrub également ne fonctionne pas, vous devriez vérifier les éléments suivants SO question, parce que pour moi cette question était en fait la réponse à mon apparition de ce problème! Rss20FeedFormatter Ignores TextSyndicationContent type for SyndicationItem.Summary

A en juger par la réponse positive de thelsdj et Andy Rose, puis plus tard, la réponse « négative » de TimLeung et l'alternative offerte par WonderGrub J'estime que le correctif proposé par cpowers a cessé de travailler dans une version ultérieure de ASP.NET ou quelque chose.

En tout cas la solution dans l'article SO ci-dessus (dérivé du code de David Whitney) a résolu le problème avec le codage HTML indésirable dans les blocs CDATA dans un flux RSS 2.0 pour moi. Je l'ai utilisé dans une application ASP.NET 4.0 WebForms.

1

Voici ce que nous avons fait:

public class XmlCDataWriter : XmlTextWriter 
     { 
      public XmlCDataWriter(TextWriter w): base(w){} 

      public XmlCDataWriter(Stream w, Encoding encoding): base(w, encoding){} 

      public XmlCDataWriter(string filename, Encoding encoding): base(filename, encoding){} 

      public override void WriteString(string text) 
      { 
       if (text.Contains("<")) 
       { 
        base.WriteCData(text); 
       } 
       else 
       { 
        base.WriteString(text); 
       } 
      } 

     } 

Et puis utiliser la classe:

public StringBuilder CDataOverwiriteMethod(Rss20FeedFormatter formatter) 
     { 
      var buffer = new StringBuilder(); 

      //could be streamwriter as well 
      using (var stream = new StringWriter(buffer)) 
      { 
       using (var writer = new XmlCDataWriter(stream)) 
       { 
        var settings = new XmlWriterSettings() {Indent = true}; 

        using (var xmlWriter = XmlWriter.Create(writer, settings)) 
        { 
         formatter.WriteTo(xmlWriter); 
        } 
       } 
      } 

      return buffer; 
     } 
0

Le chemin le plus court pour ce faire est la suivante:

.Content = SyndicationContent.CreateXhtmlContent("<![CDATA[The <em>content</em>]]>") 

qui sera émis dans le fichier XML comme

<entry> 
    … 
    <content type="xhtml"><![CDATA[The <em>content</em>]]></content> 
    … 
</entry> 

Pas une solution élégante, je le reconnais, mais cela fonctionne correctement - juste essayé sur un de mes projets.

Questions connexes