"Niektórzy ludzie, kiedy napotkają problem, myślą: 'Wiem, użyję wyrażeń regularnych'.
I teraz mają dwa problemy."

Jamie Zawinski

piątek, 10 grudnia 2010

Dynamics AX: Czytnik RSS

Kolejnym artykułem postanowiłem się podzielić z Wami, kiedy natknąłem się na swój przykład prostej aplikacji z czasów nauki programowania w Dynamics AX :) Aplikacja ta jest prostym czytnikiem kanałów RSS. Przykład w środowiskach AX może niepraktyczny, ale pomimo to można wykonać np. wyświetlanie najważniejszych informacji firmowych czy agregację najświeższych wiadomości ze świata biznesu. Dla Pani Kazi z księgowości można wyświetlać wiadomości o nowych przepisach ze świata finansów czy podatkach z portali branżowych,  a także aktualne kursy walut ... Zastosowań jak się okazuje może być mnóstwo i jest to "bajer", który może być wielu użytkownikom przydatny.

Cała aplikacja zbudowana będzie z jednej tabeli i dwóch formularzy.




1. Na początek założymy tabelę RSSTable, gdzie będziemy przechowywać listę kanałów RSS w podziale na użytkowników:
Należy dodać pola jak powyżej, a ich typy rozszerzone (Extended Data Types) nazywają się tak samo. Na tablicy oczywiście można stworzyć grupę pól składającą się np. z URL i Name.

2. Następnie stworzymy prosty formularz, gdzie będzie można uzupełniać dane kanałów. W tym celu tworzymy nowy formularz i do DataSource przeciągamy tablicę RSSTable, następnie do Grida na formularzu przeciągamy stworzoną grupę pól. Kreatywni mogą pokusić się o bardziej zaawansowane rozwiązania, lecz do moich celów w zupełności efekt końcowy jest zadowalający:

Dla przykładu dodałem wiadomości z portalu Gazeta.pl i serwisu Microsoft.

3. Czas przejść do bardziej zaawansowanego formularza, który będzie wyświetlał wiadomości z wprowadzonych kanałów RSS. W tym celu założymy nowy formularz RSS i dodamy do niego komponenty Tree i ActiveX  - Microsoft Web Broswer:




Komponent Tree będzie służył do wyświetlania kanałów wraz z nagłówkami wiadomości, a po kliknięciu na odpowiednią gałąź do przeglądarki zostanie załadowana strona z pełną zawartością artykułu.

4. Pobieranie zawartości RSS w postaci pliku XML z internetu można zrealizować na dwa sposoby:

  • pierwszy sposób za to pobieranie pliku pomocą klasy WiniInet, która już nie występuje w AX2009:
    private XmlDocument getRssXmlOld(str url)
    {
        XmlDocument rss;
        WinInet inet;
        int handle;
        TextBuffer textBuffer = new TextBuffer();
    
        ;
    
        // pobieramy xml'a
        inet = new WinInet();
        handle = inet.internetOpenUrl(url);
    
        textBuffer.appendText(inet.internetReadFile(handle));
        inet.internetCloseHandle(handle);
    
        // wczytujemy do XmlDocument
        rss = new XmlDocument();
        rss.loadXml(textBuffer.getText());
    
        return rss;
    }
  • drugi sposób to pobranie pliku za pomocą klas .NET - działa pod AX 4 i 5:
    private XmlDocument getRssXml(str url)
    {
        XmlDocument rss;
        TextBuffer textBuffer = new TextBuffer();
        System.Net.WebRequest webrequest;
        System.Net.HttpWebResponse httpresponse;
        System.IO.Stream stream;
        System.IO.StreamReader streamReader;
        str string;
        ;
    
        webrequest = System.Net.WebRequest::Create(url);
        httpresponse = webrequest.GetResponse();
    
        stream = httpresponse.GetResponseStream ();
        streamReader = new System.IO.StreamReader (stream);
    
        string = streamReader.ReadToEnd ();
    
        streamReader.Close();
        stream.Close();
        httpResponse.Close();
    
        textBuffer.appendText(string);
        // wczytujemy do XmlDocument
        rss = new XmlDocument();
        rss.loadXml(textBuffer.getText());
    
        return rss;
    }
5. Kolejnym etapem jest wypełnienie naszego komponentu Tree nagłówkami kanałów:

void setTree()
{
    FormTreeItem rssAddress;
    FormTreeItem header;
    XmlDocument rss;
    XmlNode root;
    XmlNodeList headerList;
    XmlNode message;
    XmlNode quickMessage;
    XmlNode title;
    XmlNode link;

    int i, j, nodeIndex;

    ;

    while select rssTable where rssTable.UserID == curUserID()
    {
        // pobieramy listę wiadomości z kanału rss
        root = this.getRssXml(rssTable.url).documentElement();

        try
        {
            if (root != null)
            {
                headerList = root.selectNodes("//item//link");
                rssAddress = new FormTreeItem(rssTable.Name, 0, headerList.length(), "");
                nodeIndex = tree.addItem(0 ,0, rssAddress);

                for ( i =0; i < headerList.length(); i++)
                {
                    title = headerList.item(i).selectSingleNode(strfmt("//item[link='%1']//title", headerList.item(i).text()));
                    link = headerList.item(i).selectSingleNode(strfmt("//item[link='%1']//link", headerList.item(i).text()));
                    header = new FormTreeItem(title.text(), 0, 0,link.text());

                    tree.addItem(nodeIndex, i, header);

                }
             }
         }
         catch
         {
            error("Wystąpił błąd tworzenia drzewa.");
         }
    }
}

Aby zrozumieć szerzej powyższą funkcję należałoby zrozumieć budowę pliku XML i polecenia XPath. Do tego celu polecam ciekawe lektury mojego ulubionego wydawnictwa:
6. Aby zrealizować otwieranie strony w przeglądarce po wybraniu nagłówka, należy przeciążyć metodę selectionChange na komponencie Tree:
public void selectionChanged(FormTreeItem _OldItem, FormTreeItem _NewItem, FormTreeSelect _how)
{
   super(_OldItem, _NewItem, _how);

   if (_newItem.data() != "")
   {
        ActiveX.Navigate(_newItem.data());
   }

}
7. Ostatnim etapem jest dodanie wywołania metody setTree do przeciążonej metody run na formularzu:
public void run()
{
    this.setTree();
    super();
}

Tak wygląda czytnik RSS dla Dynamics AX:



Teraz kiedy szef patrzy możemy oglądać wiadomości w DAX ;)

Brak komentarzy:

Prześlij komentarz