SyndicationFeed: контент в формате CDATA?
Я использую.NET SyndicationFeed для создания каналов 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 ответов
Это сработало для меня:
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))
Для тех, для кого решение, предоставляемое 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.
Это должно работать.
item.Content = new TextSyndicationContent("<b>Item Content</b>",TextSyndicationContentKind.Html);
У меня была та же проблема, что и в некоторых случаях, когда переопределение 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);
}
}
Это может быть слишком поздно, но я оставляю свое решение. Я добавил его как 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));
Попробуй это
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = false;
//settings.ProhibitDtd = false;
using (XmlReader reader = XmlReader.Create(rssurl, settings))
Вот что мы сделали:
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;
}
Самый короткий способ сделать это:
.Content = SyndicationContent.CreateXhtmlContent("<![CDATA[The <em>content</em>]]>")
Это будет выведено в XML как
<entry>
…
<content type="xhtml"><![CDATA[The <em>content</em>]]></content>
…
</entry>
Признаюсь, это не элегантное решение, но оно работает должным образом - только что попробовал мой проект.
Пытаться
item.Content = "<![CDATA[" +
SyndicationContent.CreateHtmlContent("<b>Item Content</b>") + "]]>";