2013-06-18 65 views
0

在SO人的幫助下,我成功實現了simple rss downloader in haskell。 但有一個問題仍然存在:如何修復Feed項目標題的破碎編碼? 這裏是最小的工作示例:修復haskell中的utf8編碼破解

import Control.Monad 
import Control.Applicative 
import Network.HTTP 
import Text.Feed.Import 
import Text.Feed.Query 
import Text.Feed.Types 
import Data.Maybe 
import qualified Data.ByteString as B 
import Network.URI (parseURI, uriToString) 
import Codec.Binary.UTF8.String (decodeString, encodeString) 

getTitleAndUrl :: Item -> (Maybe String, Maybe String) 
getTitleAndUrl item = (getItemTitle item, getItemLink item) 

downloadUri :: (Maybe String,Maybe String) -> IO() 
downloadUri (Just title,Just link) = do 
    item <- get link 
    B.writeFile title item 
    where 
     get url = let uri = case parseURI url of 
         Nothing -> error $ "invalid uri" ++ url 
         Just u -> u in 
       simpleHTTP (defaultGETRequest_ uri) >>= getResponseBody 
downloadUri _ = print "Somewhere something went Nothing" 

getTuples :: IO (Maybe [(Maybe String, Maybe String)]) 
getTuples = fmap (map getTitleAndUrl) <$> fmap (feedItems) <$> parseFeedString <$> decodeString <$> (simpleHTTP (getRequest "http://index.hu/24ora/rss/") >>= getResponseBody) 

main = getTuples 

它打印出像

Just [...,(Just "Gyalogosbaleset miatt \225ll a t\246megk\246zleked\233s a Margit h\237don",Just "http://velvet.hu/blogok/helyszinelo/2013/06/18/gyalogossbaleset_miatt_all_a_tomegkozlekedes_a_margit_hidon/"),...] 

我做了一些研究,進給其項目名稱由<![CDATA[]] sorrounded,所以XML解析器跳過他們。

示例項目:

<item> 
     <title><![CDATA[Gyalogosbaleset miatt áll a tömegközlekedés a Margit hídon]]></title> 
     <link>http://velvet.hu/blogok/helyszinelo/2013/06/18/gyalogossbaleset_miatt_all_a_tomegkozlekedes_a_margit_hidon/</link> 
     <pubDate>Tue, 18 Jun 2013 09:08:00 +0200</pubDate> 
     <category domain="main"></category> 
     <description><![CDATA[A tájékoztatás szerint a budai hídfő megállójában elesett egy gyalogos, jelenleg pótlóbuszok közlekednek.]]></description> 
     <content:encoded><![CDATA[A tájékoztatás szerint a budai hídfő megállójában elesett egy gyalogos, jelenleg pótlóbuszok közlekednek.]]></content:encoded> 
</item> 

我怎麼能強制UTF8編碼這個字符串?

+0

我不確定我是否理解這個問題。你不喜歡這裏有什麼行爲? UTF-8與它有什麼關係?如果它按照你想要的方式行事,它會有什麼不同? – shachaf

+0

@shachaf:t \ 246megk \ 246zleked \ 233s - >tömegközlekedés等等...... – pasja

+1

好的。 1:Haskell'String's是Unicode字符串。它們不是UTF-8或UTF,它們只是Unicode代碼點的列表。 2:你只是在查看'show'的結果作爲一個字符串。這就是'Show'實例的工作方式 - 你無法對此做任何事情。如果您打印字符串 - 例如用'putStrLn' - 你會發現它打印的很好。字符串是正確的,只是你看着它的方式逃脫了一些字符。 – shachaf

回答

7

好吧,我只是複製我的評論到這裏:

  1. Haskell的字符串是Unicode字符串。它們不是UTF-8或UTF,它們只是Unicode代碼點的列表。

  2. 您只是在查看字符串show的結果。這就是Show實例的工作原理 - 你無法對此做任何事情。如果您打印字符串 - 例如與putStrLn - 你會看到它打印的很好。字符串是正確的,只是你看着它的方式逃脫了一些字符。