Я пытаюсь получить данные с веб-страницы, которая периодически предоставляет файл XML с котировками на фондовом рынке ( пример данных ).Структура 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), и я попыталсянемного библиотеки 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
[]
Что-то не так?