Я пытаюсь получить данные с веб-страницы, которая периодически служит XML-файлу с котировками на фондовом рынке (sample data). Структура XML является очень простой, и что-то вроде этого:Parse XML в Haskell
<?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}
Я понимаю, более или менее, как Парсек работы (на уровне книги 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
, где я бы не иметь дело с чистой строки и создавать комбинаторы себя (я сосу у него).
EDIT: Мне, вероятно, нужно немного прочитать (как раз для того, чтобы это сделать правильно) о парсерах вообще (не только 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
[]
Что-то случилось?
Если вы заинтересованы в парсеров комбинаторов, учебник С. Doaitse Swierstra, в http://www.cs.uu.nl/research/techreps/repo/CS-2008/2008- 044.pdf, это довольно хорошее введение. Он использует аппликативный стиль, но он не предполагает знания прикладной (или теории парсеров). Я думаю, что большинство библиотек-комбайнов парсеров в Hackage (Polyparse, Attoparsec, UU-parsinglib) - лучший выбор, чем Parsec. –