株式市場の相場 (サンプル データ)を含む XML ファイルを定期的に提供する Web ページからデータを取得しようとしています。XML の構造は非常に単純で、次のようなものです。
<?xml version="1.0"?>
<Contents>
<StockQuote Symbol="PETR3" Date="21-12-2010" Time="13:20" Price="23.02" />
</Contents>
(それ以上ですが、例としてはこれで十分です)。
私はそれをデータ構造に解析したいと思います:
data Quote = Quote { symbol :: String,
date :: Data.Time.Calendar.Day,
time :: Data.Time.LocalTime.TimeOfDay,
price :: Float}
私は Parsec がどのように機能するか (Real World Haskell book のレベルで) を多かれ少なかれ理解しており、Text.XML
ライブラリを少し試してみましたが、開発できたのは機能するコードだけでしたが、そのような単純なタスクには大きすぎて、中途半端なハックであり、できる限りのことではありません。
私はパーサーと XML についてあまり知りません (基本的に RWH の本で読んだことは知っていますが、パーサーを使用したことはありません) (私は統計プログラミングと数値プログラミングを行うだけで、コンピューター科学者ではありません)。各要素を手作業で解析したり、純粋な文字列を解析したりすることなく、モデルが何であるかを判断して情報をすぐに抽出できる XML 解析ライブラリはありますか?
私は次のようなことを考えています:
myParser = do cont <- openXMLElem "Contents"
quote <- openXMLElem "StockQuote"
symb <- getXMLElemField "Symbol"
date <- getXMLElemField "Date"
(...)
closequote <- closeXMLElem "StockQuote"
closecont <- closeXMLElem "Contents"
return (symb, date)
results = parse myParser "" myXMLString
ここでは、純粋な文字列を処理してコンビネータを自分で作成する必要はありません (私はそれが嫌いです)。
編集: おそらく、一般的なパーサー (Parsec だけでなく) と XML に関する最低限のことについて、少し (これを正しく行うのに十分なだけ) 読む必要があります。皆さん、何かお勧めはありますか?
解析する必要がある実際の文字列は次のとおりです。
stringTest = "<?xml version=\"1.0\"?>\r\n<ComportamentoPapeis><Papel Codigo=\"PETR3\"
Nome=\"PETROBRAS ON\" Ibovespa=\"#\" Data=\"05/01/201100:00:00\"
Abertura=\"29,80\" Minimo=\"30,31\" Maximo=\"30,67\" Medio=\"30,36\"
Ultimo=\"30,45\" Oscilacao=\"1,89\" Minino=\"29,71\"/></ComportamentoPapeis>\r\n"
EDIT2:
私は次のことを試しました(readFloat、readQuoteTimeなどは、文字列から物を読み取るための単なる関数です)。
bvspaParser :: (ArrowXml a) => a XmlTree Quote
bvspaParser = hasName "ComportamentoPapeis" /> hasName "Papel" >>> proc x -> do
(hour,date) <- readQuoteTime ^<< getAttrValue "Data" -< x
quoteCode <- getAttrValue "Codigo" -< x
openPrice <- readFloat ^<< getAttrValue "Abertura" -< x
minim <- readFloat ^<< getAttrValue "Minimo" -< x
maxim <- readFloat ^<< getAttrValue "Maximo" -< x
ultimo <- readFloat ^<< getAttrValue "Ultimo" -< x
returnA -< Quote quoteCode (LocalTime date hour) openPrice minim maxim ultimo
docParser :: String -> IO [Quote]
docParser str = runX $ readString [] str >>> (parseXmlDocument False) >>> bvspaParser
ghciで呼び出すと:
*Main> docParser stringTest >>= print
[]
何か問題がありますか?