分析XML中的CDATA類型在RSS中的使用

          除經特別注明外,本站文章版權歸JScud Develop團隊或其原作者所有.
          轉載請注明作者和來源.  scud(飛云小俠)    歡迎訪問 JScud Develop



          根據XML中CDATA類型的規范可以知道:"&"和"<"不需要也不能被轉換. ">" 如果出現在"]]>" 的內容而不是表示結束時,必須被轉義為&gt;

          但是這樣就存在一個問題,如果我需要輸入"]]>",正確的處理是保存為"]]&gt;",但是如果我想輸入"]]&gt;",那么應該如何保存哪? 我想了很久,除非加空格或者采用特殊的辦法,否則是沒有辦法解決的.

          1.如果我們不考慮輸入"]]&gt;"的問題,來考慮一下"]]>"的處理,看看各種XML解析器是如何處理的?

          xml解析器的測試包含2個部分:設置cdata類型的數據和讀出cdata類型的數據.

          首先我們寫一個測試的例子,計劃使用JDom 1.0和Dom4j來測試一下:

           package com.jscud.test;
           
           public class XmlTestBase
           { 
               public static String xmlpart =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
                   "<xml>" +
                   "<test>"+
                   "<hello><![CDATA[ hello ]]&gt; ]]></hello>" +
                   "</test>" +
                   "</xml>";       
              
               public static void print(String str)
               {
                   System.out.println(str);
               }    
           } 


          JDom測試的例子如下:

          package com.jscud.test;
           
           import java.io.*;
           import org.jdom.*;
           import org.jdom.input.SAXBuilder;
           import org.jdom.output.*;
           
           //@author scud http://www.jscud.com
           
           public class JDomXmlFileTest extends XmlTestBase
           {
           
               public static void main(String[] args) throws Exception
               {
                   readDocument();
                   print("===========================");
                   createDocument();
               }
              
               public static void readDocument() throws Exception
               {
                   Reader reader = new StringReader(xmlpart);
                   SAXBuilder builder = new SAXBuilder();
                  
                   Document doc = builder.build(reader);
           
                   Element aRoot = doc.getRootElement();
                  
                   Element anode = aRoot.getChild("test").getChild("hello");
                  
                   print(anode.getText());       
               }
           
               public static void createDocument() throws Exception
               {       
                   Document doc = new Document();
                  
                   doc.setRootElement(new Element("root"));
                  
                   CDATA node = new CDATA("hello alt=]]&gt;");
                  
                   //throw Exception
                   //node.setText("hello]]>");
                  
                   Element ele = new Element("hello");
                  
                   ele.setContent(node);
                  
                   Element root = doc.getRootElement();
                  
                   root.getChildren().add(ele);
                  
                   XMLOutputter outputter = new XMLOutputter();
                   Format aFormat = Format.getCompactFormat();
                   aFormat.setEncoding("GB2312");
                  
                   String sResult = outputter.outputString(doc.getRootElement().getChildren());
                  
                  print(sResult);
                  
               }
           } 

           編譯并運行上面的代碼結果,我們可以看到JDom無法設置Cdata的值為"]]>",會報異常.從xml字符串讀出cdata的結果也沒有把字串"]]&gt;"翻譯為"]]>".

          接著再來測試Dom4J:

          package com.xml.test;
           
           import java.io.StringReader;
           
           import org.dom4j.*;
           import org.dom4j.io.SAXReader;
           import org.dom4j.tree.DefaultCDATA;
           
           /**
            * 測試XML的CData數據類型.
            *
            * @author scud http://www.jscud.com
            *
            */
           
           public class Dom4jXmlTest extends XmlTestBase
           {   
           
               public static void main(String[] args) throws Exception
               {
                   readDocument();
                   print("===========================");
                   createDocument();       
               }
              
               public static void createDocument()
               {
                   Document document = DocumentHelper.createDocument();
                   Element root = document.addElement( "root" );
                  
                   DefaultCDATA cdata = new DefaultCDATA("sample]]>");
                   DefaultCDATA cdata2 = new DefaultCDATA("sample]]&gt;");
                  
                   Element anode = root.addElement("cdata");
                   anode.add(cdata);
                  
                   print(anode.getText());       
                   print(anode.asXML());
                  
                   Element anode2 = root.addElement("cdata2");
                   anode2.add(cdata2);
                  
                   print(anode2.getText());       
                   print(anode2.asXML());
               }
              
               public static void readDocument() throws Exception
               {
                   StringReader strreader = new StringReader(xmlpart);
                  
                   SAXReader reader = new SAXReader();
                   Document document = reader.read(strreader);
                  
                   Node node = document.selectSingleNode( "http://test/hello" );
                  
                   print(node.getText());
                  
                   print(node.getStringValue());
               }
              
           } 

           
           我們可以看到Dom4j也是沒有做任何處理,輸入的時候不作任何轉換,原樣輸出,這樣必然導致xml錯誤.讀出的時候也沒有做轉換.

          根據上面的測試我們可以得出結論:很多xml解析器沒有正確解析cdata的數據,(jdom和dom4j用的人比較多),不要太相信這些解析器.

           

          2.我們再來看看閱讀RSS的RSS閱讀器吧,例如FeedDemon和POTU,我們準備了一個CData類型的description字段,來進行測試.

          內容:

          <?xml version="1.0" encoding="GB2312" ?>
           <rss version="2.0">
           <channel>
            <title>Some Where</title>
            <link>http://www.jscud.com/</link>
            <description />
           <item>
            <title>Test</title>
            <link>http://www.jscud.com</link>
            <author>scud</author>
            <pubDate>Mon, 22 Aug 2005 10:22:22 GMT</pubDate>
            <description><![CDATA[
            &lt;hr&gt;
            ]]&gt;
            ]]></description>
            </item>
            </channel>
            </rss>


          結果
           1.POTU沒有做任何處理
           2.FeedDemon做了處理,不過同時也把其他的&gt; &lt;等等都翻譯了,這就更不對了..
           

          本來我是打算在RSS里使用CDATA類型的description字段的,經過幾番試驗和測試,最后決定還是使用普通的description字段了,不在使用CDATA了.

          CDATA? 雞肋乎? 呵呵

           

          posted on 2005-08-22 18:49 Scud(飛云小俠) 閱讀(2604) 評論(0)  編輯  收藏 所屬分類: Java

          <2005年8月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導航

          統計

          公告

          文章發布許可
          創造共用協議:署名,非商業,保持一致

          我的郵件
          cnscud # gmail


          常用鏈接

          留言簿(15)

          隨筆分類(113)

          隨筆檔案(103)

          相冊

          友情鏈接

          技術網站

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 措勤县| 商洛市| 大洼县| 望谟县| 石屏县| 芜湖市| 龙胜| 扎兰屯市| 阿坝| 天全县| 安岳县| 富蕴县| 义马市| 临潭县| 东海县| 桐柏县| 永昌县| 商洛市| 周至县| 邵武市| 津市市| 勐海县| 玉溪市| 鲁甸县| 南昌市| 莒南县| 镇赉县| 木兰县| 逊克县| 卢龙县| 股票| 芦溪县| 库尔勒市| 崇仁县| 布尔津县| 广州市| 县级市| 达尔| 商水县| 镇雄县| 峨边|