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