1

私は。。をしようとしています

  1. CSV ファイルを読み込む
  2. ファイルから ID を読み取る
  3. ID ごとに外部 xml ファイルをロードする
  4. XML からいくつかの名前を読み取る
  5. IDと名前を新しいCSVファイルに書き出す

私はHaskellを初めて使用し、本当に学びたいと思っています.私はまだ理解のコピーと貼り付けの段階にあります. 各パーツのチュートリアルを個別に見つけましたが、それらを組み合わせるのに苦労しています。

CSV は次のように単純です。

736572,"Mount Athos"
6697806,"North Aegean"

CSV の読み取りにはCassavaを使用し、XML の読み取りにはHandsomeSoupを使用します。

ここでは、少なくとも id を読み取り、xml を読み込み、xml から名前を出力しようとしています。

{-# LANGUAGE ScopedTypeVariables #-}

import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V

import Text.XML.HXT.Core
import Text.HandsomeSoup

import Data.List
import Data.Char


getPlaceNames::String->String->String
getPlaceNames pid name = do
    let doc = fromUrl ("http://api.geonames.org/get?geonameId="++pid++"&username=demo")

    c<-runX $ doc >>> css "alternateNames" >>> deep getText
    return (head c)


main :: IO ()
main = do
    csvData <- BL.readFile "input.csv"
    case decode NoHeader csvData of
        Left err -> putStrLn err
        Right v -> V.forM_ v $ \ ( pid, name ) ->
          putStrLn $  getPlaceNames pid name

getPlaceNames を呼び出して名前を返すと、何か間違ったことをしていると思います。getPlaceNames で「do」ステートメントを使用する必要があるかどうかさえわかりません。

エラーは言う

 Couldn't match expected type ‘[[Char]]’
            with actual type ‘IO [String]’
In a stmt of a 'do' block:
  c <- runX $ doc >>> css "alternateNames" >>> deep getText
In the expression:
  do { let doc
             = fromUrl
                 ("http://api.geonames.org/get?geonameId="
                  ++ pid ++ "&username=demo");
       c <- runX $ doc >>> css "alternateNames" >>> deep getText;
       return (head c) }
In an equation for ‘getPlaceNames’:
    getPlaceNames pid name
      = do { let doc = ...;
             c <- runX $ doc >>> css "alternateNames" >>> deep getText;
             return (head c) }

しかし、それはおそらく、モナドとバインディングを理解していないために私が間違っていることの 1 つにすぎません。

適切なドキュメントへの単なるポインタであっても、助けていただければ幸いです。

乾杯

ビョルン

4

1 に答える 1

1

chi のおかげで、手順全体がわかりました。同様のことをする必要がある他の人のために、私のコードを投稿しています。

最後に、xml から名前を取得しただけでなく、複数のフィールドを取得しました。だから私はに変更getPlaceNamesしましたgtPlaceDetails

alternateNameXML からさまざまなフィールドを読み取る方法と、XML 内の要素を 1 つの文字列にマージする方法も示しているため、完全なコードを示します。

{-# LANGUAGE ScopedTypeVariables #-}


import qualified Data.ByteString.Lazy.Char8 as BL


import Data.Csv
import qualified Data.Vector as V

import Text.XML.HXT.Core
import Text.HandsomeSoup
import Data.List
import Data.Char


uppercase :: String -> String
uppercase = map toUpper


toLanguageStr :: (String, String) -> String
toLanguageStr (lan,name) = uppercase lan ++ ":" ++ name


getPlaceDetails::String->String->IO (Int,String,Float,Float,Float,Float,Float,Float,String,String)
getPlaceDetails pid name = do
    let doc = fromUrl ("http://api.geonames.org/get?geonameId="++pid++"&username=demo")

    id<-runX $ doc >>> css "geonameId" >>> deep getText
    name<-runX $ doc >>> css "name" >>> deep getText
    s<- runX $ doc >>> css "south" >>> deep getText
    w<- runX $ doc >>> css "west" >>> deep getText
    n<- runX $ doc >>> css "north" >>>  deep getText
    e<- runX $ doc >>> css "east" >>> deep getText
    lat<- runX $ doc >>> css "lat" >>> deep getText
    lng<- runX $ doc >>> css "lng" >>> deep getText
    translations<- runX $ doc >>> css "alternateName" >>> (getAttrValue "lang" &&& (deep getText))
    terms<- runX $ doc >>> css "alternateNames" >>> deep getText
    return ( read (head id),head name, read (head lat), read (head lng), read (head s), read (head w), read (head n), read (head e), intercalate "|" $ map toLanguageStr translations, head terms )



main :: IO ()
main = do
    csvData <- BL.readFile "input.csv"
    case decode NoHeader csvData of
        Left err -> putStrLn err
        Right v -> V.forM_ v $ \ ( pid, name )->do
            details <- getPlaceDetails pid name
            BL.appendFile "out.csv" $ encode [details]
            BL.putStrLn  (encode [details]) 

たとえば、input.csv 行

736572,"Mount Athos"

これを out.csv にマップします

736572,"Mount Athos",40.15798,24.33021,40.11294,23.99234,40.4563,24.40044,"KO:아토스 산|:Aftónomos Periochí Agíou Órous|:Ágion Óros|:Ágio Óros|:Athos|NO:Áthos|EN:Autonomous Monastic State of the Holy Mountain|:Avtonómos Periokhí Ayíou Órous|:Áyion Óros|:Dhioíkisis Ayíou Órous|:Hagion Oros|:Holy Athonite Republic|LINK:http://en.wikipedia.org/wiki/Mount_Athos|CA:Mont Athos|FR:Mont Athos|EN:Mount Athos|FR:République monastique du Mont Athos|EL:Αυτόνομη Μοναστική Πολιτεία Αγίου Όρους","Aftonomos Periochi Agiou Orous,Aftónomos Periochí Agíou Órous,Agio Oros,Agion Oros,Athos,Autonome Monastike Politeia Agiou Orous,Autonomous Monastic State of the Holy Mountain,Avtonomos Periokhi Ayiou Orous,Avtonómos Periokhí Ayíou Órous,Ayion Oros,Dhioikisis Ayiou Orous,Dhioíkisis Ayíou Órous,Hagion Oros,Holy Athonite Republic,Mont Athos,Mount Athos,Republique monastique du Mont Athos,République monastique du Mont Athos,atoseu san,Ágio Óros,Ágion Óros,Áthos,Áyion Óros,Αυτόνομη Μοναστική Πολιτεία Αγίου Όρους,아토스 산"
于 2016-06-16T10:37:38.897 に答える