posts - 262,  comments - 221,  trackbacks - 0
          Informa不僅提供了對不同版本的RSS Feed source的讀入和解析,同樣也提供了將channel object導出為不同協議版本的XML文件的功能。這個功能是通過exporters包下的各個導出類來完成的。目前僅支持對RSS協議的導出,不支持Atom協議、OPML協議的導出。

          所有的導出類都實現了ChannelExporterIF接口
          /**
           * A channel exporter is used to write channel objects in an
           * implementation dependent way to an implicit destination.</p>
           *
           * 
          @author Niko Schmuck (niko@nava.de) 
           
          */

          public interface ChannelExporterIF {

            
          /**
             * Writes the given channel to an implicit implementation dependent
             * destination.
             *
             * 
          @param channel - The channel to be exported/written;
             *                  an object implementing ChannelIF.
             * 
          @throws IOException - Thrown if writing the channel fails.
             
          */

            
          void write(ChannelIF channel) throws IOException;

          }

          ★RSS_0_91_Exporter

          RSS_0_91_Exporter中提供了幾種構造方法
          public RSS_0_91_Exporter(String filename) throws IOException {
              
          this(new File(filename), "utf-8");
          }


          public RSS_0_91_Exporter(File file) throws IOException {
              
          this(file, "utf-8");
          }


          public RSS_0_91_Exporter(File file, String encoding) throws IOException {
              
          this.writer = new OutputStreamWriter(new FileOutputStream(file),
              encoding);
              
          this.encoding = encoding;
          }


          public RSS_0_91_Exporter(Writer writer, String encoding) {
              
          this.writer = writer;
              
          this.encoding = encoding;
          }

          真正的生成XML文件的過程其實很簡單,就是按照RSS 0.9.1規范的格式將channel object的屬性映射到XML文件的element去。
                  // create items for channel
                  Collection<ItemIF> items = channel.getItems();
                  Iterator
          <ItemIF> it = items.iterator();
                  
          while (it.hasNext()) {
                      ItemIF item 
          = (ItemIF) it.next();
                      Element itemElem 
          = new Element("item");
                      itemElem.addContent(
          new Element("title").
                              setText(item.getTitle()));
                      
          if (item.getLink() != null{
                          itemElem.addContent(
          new Element("link").
                                  setText(item.getLink().toString()));
                      }

                      
          if (item.getDescription() != null{
                          itemElem.addContent(
          new Element("description").
                                  setText(item.getDescription()));
                      }

                      
          if (item.getDate() != null{
                          itemElem.addContent(
          new Element("pubDate").
                                  setText(ParserUtils.formatDate(item.getDate())));
                      }

                      channelElem.addContent(itemElem);
                  }

          這是write(Channel)方法的其中一個片段,是用于導出channel中的item節點的。

          RSS_2_0_Exporter

          和RSS 0.9.1的導出類似,2.0版本的導出同樣需要實現ChannelExporterIF接口,同樣提供了和上面一樣參數類型的構造方法。不同的是在2.0的版本,由于新增了幾個定義,所以增加了對應的構建方法。例如下面的getCategoryElements方法

              // ------------------------------------------------------------
              
          // Build a hierarchical category String from CategoryIF
              
          // ------------------------------------------------------------

              
          private Element getCategoryElements(Element elem, CategoryIF category,
                      StringBuffer catString) 
          {
                  StringBuffer l_catString;
                  
          if (catString == null || catString.length() < 1)
                      l_catString = new StringBuffer(category.getTitle());

                  
          else
                      l_catString = catString.append("/").append(category.getTitle());


                  Collection
          <CategoryIF> categories = category.getChildren();
                  
          if (categories.size() == 0{
                      elem.addContent(
          new Element("category").setText(l_catString
                              .toString()));
                  }
           else {
                      Iterator
          <CategoryIF> catIt = categories.iterator();
                      
          while (catIt.hasNext()) {
                          CategoryIF childCat 
          = (CategoryIF) catIt.next();
                          elem = getCategoryElements(elem, childCat, l_catString);

                      }

                  }

                  
          return elem;
              }

          這個方法采用遞歸的方式,獲取一個channel所屬于的category,因為在Category對象中,關系是以級聯的方式存在的,要把這種對象的級聯關系展開為平行的字符串,只能通過遞歸的方式訪問到最底層的category對象,得到其title后,再用分隔符"/"拼接后返回給上一層。

          在2.0的write方法中,新增了對Namespace的支持
           Namespace dcNs = Namespace.getNamespace("dc", NS_DC);
           Namespace syNs 
          = Namespace.getNamespace("sy", NS_SY);
           Namespace adminNs 
          = Namespace.getNamespace("admin", NS_ADMIN);

          其余的生成過程和0.9.1的基本相同,除了在category方面
                  if (channel.getCategories() != null{
                      Collection<CategoryIF> categories = channel.getCategories();

                      Iterator
          <CategoryIF> catIt = categories.iterator();
                      
          while (catIt.hasNext()) {
                          CategoryIF cat 
          = (CategoryIF) catIt.next();
                          channelElem = getCategoryElements(channelElem, cat, null);

                      }

                  }

          RSS_1_0_Exporter

          RSS_1_0_Exporter導出和0.9.1和2.0協議的過程有些不同,區別在于item方面和部分屬性,這里重點介紹一下item方面的導出過程
                  // ===========================================
                  Element itemsElem = new Element("items", defNs);
                  Element seqElem 
          = new Element("Seq", rdfNs);
                  Collection
          <ItemIF> items = channel.getItems();
                  Iterator
          <ItemIF> it = items.iterator();
                  
          while (it.hasNext()) {
                      ItemIF item 
          = (ItemIF) it.next();
                      Element itemElem 
          = new Element("li", rdfNs);
                      
          if (item.getLink() != null{
                          itemElem.setAttribute(
          "resource", item.getLink().toString());
                      }

                      seqElem.addContent(itemElem);
                  }

                  itemsElem.addContent(seqElem);
                  channelElem.addContent(itemsElem);
                  rootElem.addContent(channelElem);

                  
          // item-by-item en detail
                  items = channel.getItems();
                  it 
          = items.iterator();
                  
          while (it.hasNext()) {
                      ItemIF item 
          = (ItemIF) it.next();
                      Element itemElem 
          = new Element("item", defNs);
                      
          if (item.getLink() != null{
                          itemElem.setAttribute(
          "about"
                              item.getLink().toString(), rdfNs);
                      }

                      itemElem.addContent(
          new Element("title", defNs).
                              setText(item.getTitle()));
                      
          if (item.getLink() != null{
                          itemElem.addContent(
          new Element("link", defNs).
                              setText(item.getLink().toString()));
                      }

                      
          if (item.getDescription() != null{
                          itemElem.addContent(
          new Element("description", dcNs).
                              setText(item.getDescription()));
                      }

                      
          if (item.getDate() != null{
                          itemElem.addContent(
          new Element("date", dcNs).
                              setText(ParserUtils.formatDate(item.getDate())));
                      }


                      rootElem.addContent(itemElem);
                  }

          和0.9.1和2.0協議不同,1.0的RSS對于item的描述有2次,第一次是summary,第二次是detail。
          <items>
                
          <rdf:Seq>
                  
          <rdf:li resource="http://xml.com/pub/2000/08/09/xslt/xslt.html" />
                  
          <rdf:li resource="http://xml.com/pub/2000/08/09/rdfdb/index.html" />
                
          </rdf:Seq>
              
          </items>

          <item rdf:about="http://xml.com/pub/2000/08/09/xslt/xslt.html">
              
          <title>Processing Inclusions with XSLT</title>
              
          <link>http://xml.com/pub/2000/08/09/xslt/xslt.html</link>
              
          <description>
               Processing document inclusions with general XML tools can be 
               problematic. This article proposes a way of preserving inclusion 
               information through SAX-based processing.
              
          </description>
            
          </item>
            
            
          <item rdf:about="http://xml.com/pub/2000/08/09/rdfdb/index.html">
              
          <title>Putting RDF to Work</title>
              
          <link>http://xml.com/pub/2000/08/09/rdfdb/index.html</link>
              
          <description>
               Tool and API support for the Resource Description Framework 
               is slowly coming of age. Edd Dumbill takes a look at RDFDB, 
               one of the most exciting new RDF toolkits.
              
          </description>
            
          </item>

          可以看到上面的<items>是大概地告知了RSS閱讀器這個channel下面有多少個item,順序如何。下面每一個<item>則是對上面提到的item的詳細描述。根據規范,<item>節點的rdf:about屬性值必須和rdf:li的resource屬性值一樣。

          上面的代碼就是先找出item的列表,構建<items>節點及其子節點<rdf:seq>,后面是構建<item>節點。所以有2次的節點迭代操作。


          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2010-01-04 10:15 Paul Lin 閱讀(410) 評論(0)  編輯  收藏 所屬分類: J2SE
          <2010年1月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 田东县| 洛宁县| 平果县| 军事| 玉树县| 堆龙德庆县| 墨竹工卡县| 盖州市| 青川县| 武山县| 白山市| 五大连池市| 墨脱县| 岳普湖县| 仙居县| 嘉兴市| 金寨县| 丹东市| 海门市| 任丘市| 新沂市| 行唐县| 陕西省| 潮安县| 陈巴尔虎旗| 高邮市| 巴楚县| 平舆县| 张家川| 宜宾市| 横峰县| 略阳县| 无为县| 广汉市| 秦皇岛市| 方城县| 永靖县| 兰坪| 诏安县| 衡南县| 灌阳县|