SyndicateFeed:内容为 CDATA?

发布于 2024-07-27 15:40:21 字数 691 浏览 8 评论 0原文

我正在使用 .NET 的 SyndicateFeed 来创建 RSS 和 ATOM 提要。 不幸的是,我需要在描述元素(SyndicateItem 的 Content 属性)中包含 HTML 内容,并且格式化程序会自动对 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;

有人知道我如何使用 SyndicateFeed 来做到这一点吗? 我的最后一招是“手动”为提要创建 XML,但我宁愿使用内置的 SyndicateFeed。

I'm using .NET's SyndicationFeed to create RSS and ATOM feeds. Unfortunately, I need HTML content in the description element (the Content property of the SyndicationItem) and the formatter automatically encodes the HTML, but I'd rather have the entire description element wrapped in CDATA without encoding the HTML.

My (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;

Anybody an idea how I can do this using SyndicationFeed? My last resort is to "manually" create the XML for the feeds, but I'd rather use the built-in SyndicationFeed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

没有心的人 2024-08-03 15:40:21

这对我有用:

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

This worked for me:

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

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

then you can:

new CDataSyndicationContent(new TextSyndicationContent(content, TextSyndicationContentKind.Html))
九八野马 2024-08-03 15:40:21

对于那些 cpowers 和 WonderGrub 提供的解决方案也不起作用的人,您应该查看以下 SO 问题,因为对我来说,这个问题实际上是我出现此问题的答案!
Rss20FeedFormatter 忽略 SyndicateItem.Summary 的 TextSyndicateContent 类型

从肯定答案来看thelsdjAndy Rose,然后是 TimLeung 的“否定”回应以及 WonderGrub 提供的替代方案,我会估计 cpowers 提供的修复程序在某些更高版本的 ASP.NET 或其他版本中停止工作。

无论如何,上述 SO 文章(源自 David Whitney 的代码)中的解决方案为我解决了 RSS 2.0 提要中的 CDATA 块中不需要的 HTML 编码的问题。 我在 ASP.NET 4.0 WebForms 应用程序中使用了它。

For those for whom the solution provided by cpowers and WonderGrub also didn't work, you should check out the following SO question, because for me this question was actually the answer to my occurence of this problem!
Rss20FeedFormatter Ignores TextSyndicationContent type for SyndicationItem.Summary

Judging from the positive answer from thelsdj and Andy Rose and then later the 'negative' response from TimLeung and the alternative offered by WonderGrub I would estimate that the fix offered by cpowers stopped working in some later version of ASP.NET or something.

In any case the solution in the above SO article (derived from David Whitney's code) solved the problem with unwanted HTML encoding in CDATA blocks in an RSS 2.0 feed for me. I used it in an ASP.NET 4.0 WebForms application.

中性美 2024-08-03 15:40:21

这应该有效。

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

This should work.

item.Content =  new TextSyndicationContent("<b>Item Content</b>",TextSyndicationContentKind.Html);
百思不得你姐 2024-08-03 15:40:21

我遇到了与 cpowers 示例中未调用 WriteContentsTo 覆盖的某些问题相同的问题(仍然不知道为什么)。 因此,我将其更改为从 SyndicateContent 类继承。 不确定这是否是最好的解决方案,但在我的情况下效果很好。

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

I had the same problem as some where the WriteContentsTo override wasn't being called in cpowers example (still no idea why). So, I changed it to inherit from the SyndicationContent class instead. Not sure if this is the best solution, but worked great in my 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);
    }
}
如果没有 2024-08-03 15:40:21

可能为时已晚,但我留下了我的解决方案。 我将它添加为 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));

It might be too late but I leave my solution. I added it as a ElementExtension then it works for me. My environment is .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));
暖阳 2024-08-03 15:40:21

尝试这个

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

try this

XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreComments = false;
            //settings.ProhibitDtd = false;
            using (XmlReader reader = XmlReader.Create(rssurl, settings))
季末如歌 2024-08-03 15:40:21

这是我们所做的:

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

Here is what we did :

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

       }

And then to use the class :

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;
       }
忆依然 2024-08-03 15:40:21

执行此操作的最短方法是:

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

这将在 XML 中输出为

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

我承认这不是一个优雅的解决方案,但它工作正常 - 刚刚在我的一个项目上尝试过。

The shortest way to do this is:

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

That will be outputted in the XML as

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

Not an elegant solution, I admit, but it works properly – just tried on a project of mine.

二手情话 2024-08-03 15:40:21

尝试

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

try

item.Content = "<![CDATA[" + 
            SyndicationContent.CreateHtmlContent("<b>Item Content</b>") + "]]>";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文