RSS – Um Guia para Desenvolvedor (Parte 2)

Fernando Cerqueira

RSS quer dizer: RDF Site Summary, “Rich Site Sumary” ou “Really Simples Syndication”. Isso já foi visto na primeira parte deste artigo. Vimos também que existem 2 versão no momento : A RSS 1.0 (que segue a especificação RDF do w3c) e a RSS 2.0 que não tem este compromisso . Ficamos também sabendo do projeto ATOM que tem a proposta de unificar as 2 versões.

Foi detalhada na parte 1 cada elemento da especificação 2.0 que será a base para a criação desta classe que iremos detalhar nesta segunda parte.

Início da páginaInício da página

O projeto de criação da classe Rss2Lib

A estratégia para criação foi criar diversas classes especializadas que irão cuidar de cada elemento mais complexo ou de uma coleção de elementos. Alem das classes especializadas de cada elemento foram criados enum para melhorar a legibilidade de alguns elementos.

Para auxiliar a validação e geração, cada casse especializada contará com um método padronizado e especifico de validação e preenchimento que será orquestrada pela classe principal.

Início da páginaInício da página

A organização das classes

O projeto foi divido nas seguintes classes:

Rss2Util – Classe de apoio com diversas funções de conversão e transformação.

Rss2Enum – Classe com as enumerações para alguns elementos.

Rss2Categoria Rss2Categoria – especializada no elemento <category></category> que ocorre no chanel e o item, onde são definidas as categorias.

Rss2CategoriaColletion – Coleção da classe Rss2Categoria

Rss2Cloud - especializada no elemento <cloud></cloud> que define as interfaces para suporte a integração com web services

Rss2Enclosure - especializada no elemento <enclosure></enclosure> que descreve um local, tamanho e tipo de um arquivo que pode ser baixado e que faz parte do documento com um anexo em separado.

Rss2Guid - especializada no elemento <guid></guid> que descreve de forma única o item dentro do documento e também sobre qualquer outro documento.

Rss2Image - especializada no elemento <image></image> que informa um arquivo de imagem do tipo GIF, JPEG ou PNG

Rss2SkipHoursColletion - especializada no elemento <skipHours></skipHours> que informar as horas em que o canal que origina o documento não esta disponível para leitura ou não terá atualização.

Rss2SkipDaysColletion - especializada no elemento <skipDays></skipDays> que informar os dias da semana que o canal que origina o documento não esta disponível para leitura ou não terá atualização.

Rss2Source - especializada no elemento <source></source> que informar a fonte de dados que originou a informação

Rss2TextInputRss2TextInput - especializada no elemento <textinput></textinput> que criar uma interação com o usuário para uma entrada de dados

Rss2Channel - especializada no elemento <channel></channel> que descreve as características e itens que estão sendo disponibilizados no documento.

Rss2Item - especializada no elemento <item></item> que descreve os tópicos, artigos, noticias que se deseja informar no documento.

Rss2ItemColletion – Coleção da classe Rss2Item.

Rss2Feed – Classe principal que engloba as demais classes e os principais métodos.

Início da páginaInício da página

Código e comentários das classes

Optamos por não transcrever na integra todo o código no artigo devido a sua extensão, estando disponível ao final do artigo um link para todo o código fonte da classe juntamente com um exemplo de uso.

Para cada classe é feito um comentário ou destaque de uma implementação relevante para que se possa mostrar alguns recursos disponíveis em .NET

Rss2Enum – Classe com as enumerações para alguns elementos. A grande vantagem de enumeração, a nosso ver, é a legibilidade para o desenvolvedor apresentando durante a codificação os domínios de valores para uma determinada variável, propriedade e/ou parâmetro. Outro ponto interessante nesta classe é o uso de palavra reservada para definir um elemento de uma enumeração. Ex: nothing.

Dica: quando se necessita definir um elemento de linguagem com uma palavra reservada existe uma feature : “Escaped identifiers" que para o vb.net é o colchete [...] e para o c# é o arroba @. Um detalhe maior pode ser visto em (http://br.thespoke.net/BlogReader/SingleEntry.aspx?ID=5991)

Public Class Rss2Enum
    Public Enum RssMimeTypes
        [nothing] = 0
        Textrichtext = 1
        TextHtml = 2
        audioxaiff = 3
	  ...
	  ...
    End Enum
    ...
    ...
End Class

Rss2Util – Classe de apoio com diversas funções de conversão e transformação. O destaque fica por conta de 2 funções que fazem a transformação e retorno a forma original de alguns caracteres inválidos para elemento dentro de um conteúdo no formato XML.

Rss2Util 
    Public Shared Function FormatStringXML(ByVal Value As String) As String
        Value = Value.Replace("&", "&")
        Value = Value.Replace("\", """)
        Value = Value.Replace("'", "'")
        Value = Value.Replace("<", "<")
        Value = Value.Replace(">", ">")
        Return Value
    End Function

    Public Shared Function UnFormatStringXML(ByVal Value As String) As String
        Value = Value.Replace("&", "&")
        Value = Value.Replace(""", "\")
        Value = Value.Replace("'", "'")
        Value = Value.Replace("<", "<")
        Value = Value.Replace(">", ">")
        Return Value
    End Function

Rss2Categoria, Rss2Channel, Rss2Cloud, Rss2Enclosure, Rss2Guid, Rss2Image, Rss2Item, Rss2Source, Rss2TextInput– Classes que definem diversos elementos da especificação RSS 2.0. Como destaques, podemos citar uma padronização em cada classe para auxiliar a validação e geração:

ErrorDescription - que descreve um erro de conteúdo na classe
IsGenerate() - Define se a classe de um elemento esta preenchida ou não.
IsValid() – Define se a classe de um elemento é válida ou não.

Rss2CategoriaColletion, Rss2ItemColletion, Rss2SkipDaysColletion, Rss2SkipHoursColletion– Classes que definem a coleções de diversos elementos da especificação RSS 2.0. Como destaque fica um exemplo de como implementar uma coleção herdando da classe CollectionBase, criado-se assim uma coleção especializada para cada classe. Abaixo um exemplo pela classe Rss2SkipHoursColletion:


Rss2CategoriaColletion, Rss2ItemColletion, Rss2SkipDaysColletion, 
Rss2SkipHoursColletion Public Class Rss2SkipHoursColletion
    Inherits CollectionBase
    ...	
    ...	
    Public Property Item(ByVal Index As Integer) As Rss2Enum.RssSkipHours
        Get
            Return list(Index)
        End Get
        Set(ByVal Value As Rss2Enum.RssSkipHours)
            list(Index) = Value
        End Set
    End Property
    Public Function Add(ByVal Item As Rss2Enum.RssSkipHours) As Integer
        Return list.Add(Item)
    End Function
    Public Function IndexOf(ByVal Item As Rss2Enum.RssSkipHours) As Integer
        Return list.IndexOf(Item)
    End Function
    Public Sub Insert(ByVal Index As Integer, ByVal Item As Rss2Enum.RssSkipHours)
        list.Insert(Index, Item)
    End Sub
    Public Sub Remove(ByVal Item As Rss2Enum.RssSkipHours)
        list.Remove(Item)
    End Sub
    Public Shadows Sub RemoveAt(ByVal Index As Integer)
        list.RemoveAt(Index)
    End Sub
    Public Function Contains(ByVal Item As Rss2Enum.RssSkipHours) As Boolean
        Return list.Contains(Item)
    End Function
    Protected Overrides Sub OnInsert(ByVal Index As Integer, ByVal Item As Object)
        If Not Item.GetType() Is Type.GetType("Rss2Lib.Rss2Enum+RssSkipHours") Then
            Throw New ArgumentException("Item não é um RssSkipHours!")
        End If
    End Sub
    Protected Overrides Sub OnRemove(ByVal Index As Integer, ByVal Item As Object)
        If Not Item.GetType() Is Type.GetType("Rss2Lib.Rss2Enum+RssSkipHours") Then
            Throw New ArgumentException("Item não é um RssSkipHours!")
        End If
    End Sub
    Protected Overrides Sub Onset(ByVal Index As Integer, ByVal OldItem As Object,
    ByVal NewItem As Object)
        If Not NewItem.GetType() Is Type.GetType("Rss2Lib.Rss2Enum+RssSkipHours") Then
            Throw New ArgumentException("Item não é um RssSkipHours!")
        End If
    End Sub
    Protected Overrides Sub OnValidate(ByVal Item As Object)
        If Not Item.GetType() Is Type.GetType("Rss2Lib.Rss2Enum+RssSkipHours") Then
            Throw New ArgumentException("Item não é um RssSkipHours!")
        End If
    End Sub
    ...	 
    ...	
End Class

Dica: Outro destaque que vale citar é a forma de referenciar type de enumeração pelo VB: pelo Token “Mais” + Ex: . . . Type.GetType("Rss2Lib.Rss2Enum+RssSkipHours")

Rss2Feed– Classe principal que engloba as demais classes. Alem de conter nas propriedades as demais classes foram criados os seguintes métodos para o desenvolvedor:

IsRss2FeedValid() – Valida se um Documento RSS esta em conformidade com a especificação 2.0

ToFile() – gera um arquivo RSS baseado nas propriedades da classe . O arquivo é gerado no path definido pela propriedade: FilePathOutput.

ToString() – retorna uma string com um documento RSS na versão 2.0.

ReadFrom() – Lê um arquivo RSS “arquivando” seus dados na classe

Outros pontos que podem ser uma boa fonte de exemplo e estudo é o uso da classe System.IO - MemoryStream que manipula uma stream em memória e a classe System.Xml – XmlReader e XmlTextWriter para ler e gerar arquivos no formato XML.

Início da páginaInício da página

Exemplo de código usando a Classe RSS2LIB

	  'Lendo e valdanddo um arquivo RSS
        Dim RssFile As New Rss2Lib.Rss2Feed
	  RssFile.ReadFrom("C:\XMLFile1.xml")
        If Not RssFile.IsRss2FeedValid Then
            MsgBox(RssFile.ErrorDescrpition)
        End If
	  'gerando um Arquivo RSS
        RssFile = New Rss2Lib.Rss2Feed
	  'Chanel
        RssFile.Channel.Title = "Teste"
        RssFile.Channel.Link = "http://www.gurj.net "
        RssFile.Channel.Description = "Teste de geração"
        RssFile.Channel.Language = Rss2Lib.Rss2Enum.RssLanguange.PortugueseBrazil
        RssFile.Channel.Copyright = "GURJ.NET – GRUPO DE USUARIOS DO RIO DE JANEIRO"
        RssFile.Channel.ManagingEditor = "fernandocerqueira@gurj.net"
        RssFile.Channel.PubDate = System.DateTime.Now
        RssFile.Channel.Categoria.Add("teste")
        RssFile.Channel.Generator = "RSS2LIB"
        RssFile.Channel.Docs = "http://backend.userland.com./rss"
        RssFile.Channel.cloud.Domain = "WWW.FCI.COM.BR"
        RssFile.Channel.SkipHours.Add(Rss2Lib.Rss2Enum.RssSkipHours.Dezoito)
        RssFile.Channel.SkipDays.Add(Rss2Lib.Rss2Enum.RssSkipDays.Domingo)
	  'item – exemplo 1
        RssFile.Itens.Add("teste", "xyz", "ftp://www.fci.com.br/art=12&teste=xxx",
        "fernandocerqueira@gurj.net", Nothing)
	  'item – exemplo 2
        Dim Item As New Rss2Lib.Rss2Item
        Item.Author = "fcerqueira@fci.com.br"
        Item.Categoria.Add("ccc", "WWW.FCI.COM.BR")
        Item.Comments = "zczczxc"
        Item.Description = "zcxczxczx"
        Item.Enclosure.Length = 12
        Item.Enclosure.Type = Rss2Lib.Rss2Enum.RssMimeTypes.imagepjpeg
        Item.Enclosure.Url = "www.fci/cs"
        Item.Guid.Guid = "WWW.FCI.COM.BR"
        Item.Guid.IsPermamentLink = True
        Item.Link = "www.gurj.net"
        Item.PubDate = System.DateTime.Now
        Item.Source.Text = "texto source"
        Item.Source.Url = "gurj.net"
        Item.Title = "titulo"
        RssFile.Itens.Add(Item)
	  'validando o conteúdo e gerando o arquivo
        If RssFile.IsRss2FeedValid Then
            Dim X As String = RssFile.ToString
        End If
Início da páginaInício da página

Conclusão

Com este artigo encerramos este guia sobre RSS. A classe RSS2LIB foi testada porem é passível de existirem bug. Alem disso com certeza ela pode e deve ser evoluída e melhorada, e aproveitamos para convidar todos os desenvolvedores do MSDN Brasil a colaborar em sua melhoria participando do Hub de RSS do THE SPOKE (http://br.thespoke.net)

Até o Próximo artigo ou nas entradas do HUB de RSS onde serão concentradas as melhorias e implementações e sugestões desta classe alem de debates sobre a especificação RSS.

Início da páginaInício da página

Link para Download da Classe

Abaixo o link para a o arquivo que se encontra compactado contendo as fontes da classe.

http://www.gurj.net/GRUPO/Downloads/DldAplicativos/265.aspx

Início da páginaInício da página

Link para o Hub do The Spoke

Abaixo o link para ao HUB do THE SPOKE onde poderá encontrar mais informação e poder debater com a comunidade as especificações do padrão RSS.

http://br.thespoke.net/Hubs/Hubs_Hub.aspx?categoryid=5754&cat=1

Início da páginaInício da página

Referências:

Especificação RSS 2.0

Especificação RSS 1.0

Projeto Atom


Início da páginaInício da página