SyndicationFeed: контент в формате CDATA? - PullRequest
4 голосов
/ 13 июля 2009

Я использую SynticationFeed .NET для создания каналов RSS и ATOM. К сожалению, мне нужно содержимое HTML в элементе description (свойство Content объекта SyndicationItem), и средство форматирования автоматически кодирует HTML, но я бы предпочел, чтобы весь элемент описания был заключен в CDATA без кодирования HTML.

Мой (простой) код:

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;

Кто-нибудь знает, как я могу сделать это с помощью SyndicationFeed? Мое последнее средство - «вручную» создать XML для каналов, но я бы лучше использовал встроенный SyndicationFeed.

Ответы [ 9 ]

8 голосов
/ 05 февраля 2011

Это сработало для меня:

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

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

тогда вы можете:

new CDataSyndicationContent(new TextSyndicationContent(content, TextSyndicationContentKind.Html))
4 голосов
/ 24 мая 2013

Для тех, для кого решение, предоставляемое cpowers и WonderGrub, также не сработало, вам следует проверить следующий ТАК вопрос, потому что для меня этот вопрос был фактически ответом на мое возникновение этой проблемы! Rss20FeedFormatter Игнорирует тип TextSyndicationContent для SyndicationItem.Summary

Судя по положительному ответу от thelsdj и Andy Rose, а затем и по "отрицательному" ответу от TimLeung и альтернативе, предложенной WonderGrub, я бы оценил, что исправление, предлагаемое cpowers, перестало работать через некоторое время версия ASP.NET или что-то.

В любом случае решение в вышеприведенной статье SO (полученной из кода Дэвида Уитни) решило проблему с нежелательным кодированием HTML в блоках CDATA в канале RSS 2.0 для меня. Я использовал его в приложении ASP.NET 4.0 WebForms.

3 голосов
/ 10 марта 2010

Это должно работать.

item.Content =  new TextSyndicationContent("<b>Item Content</b>",TextSyndicationContentKind.Html);
2 голосов
/ 05 декабря 2018

Это может быть слишком поздно, но я оставляю свое решение. Я добавил его как ElementExtension, тогда он работает для меня. Моя среда .NET 4.5.

XNamespace nsDefault = "http://www.w3.org/2005/Atom";
var content = new XElement(nsDefault + "content");
content.Add(new XCData("<b>Item Content</b>"));
item.ElementExtensions.Add(new SyndicationElementExtension(content));
2 голосов
/ 11 апреля 2013

У меня была та же проблема, что и в некоторых случаях, когда переопределение WriteContentsTo не вызывалось в примере cpowers (до сих пор не знаю почему). Итак, я изменил его, чтобы наследовать от класса SyndicationContent вместо этого. Не уверен, что это лучшее решение, но отлично сработало в моей ситуации.

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);
    }
}
1 голос
/ 03 февраля 2014

Вот что мы сделали:

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

       }

А потом использовать класс:

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;
       }
1 голос
/ 15 ноября 2010

попробуйте

XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreComments = false;
            //settings.ProhibitDtd = false;
            using (XmlReader reader = XmlReader.Create(rssurl, settings))
0 голосов
/ 15 февраля 2015

Самый короткий способ сделать это:

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

Это будет выведено в XML как

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

Признаюсь, это не элегантное решение, но оно работает правильно - только что попробовал мой проект.

0 голосов
/ 13 июля 2009

попробуй

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