Ich versuche, Daten von einer Webseite zu erhalten, die eine XML-Datei regelmäßig mit Börsenkursnotierungen (sample data) liefert. Die Struktur des XML ist sehr einfach, und ist so etwas wie diese:Parse XML in Haskell
<?xml version="1.0"?>
<Contents>
<StockQuote Symbol="PETR3" Date="21-12-2010" Time="13:20" Price="23.02" />
</Contents>
(es ist mehr als das, aber das genügt als Beispiel).
Ich mag es auf eine Datenstruktur analysieren:
data Quote = Quote { symbol :: String,
date :: Data.Time.Calendar.Day,
time :: Data.Time.LocalTime.TimeOfDay,
price :: Float}
Ich verstehe, mehr oder weniger, wie Parsec Werke (auf der Ebene des Real World Haskell Buch), und ich versuchte, ein wenig die Text.XML
Bibliothek, aber alles, was ich entwickeln konnte, war ein Code, der funktionierte, aber für eine so einfache Aufgabe zu groß ist und wie ein halbgebackener Hack aussieht und nicht der Beste, den man tun könnte.
Ich weiß nicht viel über Parser und XML (Ich weiß im Grunde, was ich im RWH Buch gelesen habe, ich habe nie zuvor Parser verwendet) (Ich mache nur statistische und numerische Programmierung, ich bin kein Informatiker) . Gibt es eine XML-Parsing-Bibliothek, in der ich einfach sagen könnte, was das Modell ist und die Informationen sofort extrahiere, ohne jedes Element von Hand analysieren zu müssen und ohne reine Zeichenfolge analysieren zu müssen?
Ich denke an so etwas wie:
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
, wo ich würde nicht mit dem reinen Zeichenfolge zu tun haben, und erstellen Sie die combinators mich (ich es saugen).
EDIT: Ich muss wahrscheinlich ein wenig (gerade genug, um dies richtig gemacht) über Parser im Allgemeinen (nicht nur Parsec) und das Minimum über XML zu lesen. Kannst du etwas empfehlen?
Die eigentliche Zeichenfolge ich zu analysieren haben, ist dies:
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:
habe ich versucht, die folgende (readfloat, readQuoteTime, etc ... sind nur Funktionen Dinge von Strings zu lesen).
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
Als ich es in GHCI nennen:
*Main> docParser stringTest >>= print
[]
etwas falsch?
Wenn Sie in Parser Kombinatoren interessiert, S. Doaitse Swierstra Tutorial, http://www.cs.uu.nl/research/techreps/repo/CS-2008/2008- 044.pdf, ist eine ziemlich gute Einführung. Es verwendet den Anwendungsstil, aber es setzt keine Kenntnisse der Applicative (oder Parser-Theorie) voraus. Ich denke, die meisten Parser-Kombinator-Bibliotheken auf Hackage (Polyparse, Attoparsec, UU-Parsinglib) sind eine bessere Wahl als Parsec. –