Parse XML in Haskell Parse XML in Haskell xml xml

Parse XML in Haskell


There are plenty of XML libraries written for Haskell that can do the parsing for you. I recommend the library called xml (see http://hackage.haskell.org/package/xml). With it, you can simply write e.g.:

let contents = parseXML source    quotes   = concatMap (findElements $ simpleName "StockQuote") (onlyElems contents)    symbols  = map (findAttr $ simpleName "Symbol") quotes    simpleName s = QName s Nothing Nothingprint symbols

This snippet prints [Just "PETR3"] as a result for your example XML, and it's easy to extend for collecting all the data you need. To write the program in the style you describe you should use the Maybe monad, as the xml lookup functions often return a Maybe String, signaling whether the tag, element or attribute could be found. Also see a related question: Which Haskell XML library to use?


The following snippet uses xml-enumerator. It leaves date and time as text (parsing those is left as an exercise to the reader):

{-# LANGUAGE OverloadedStrings #-}import Text.XML.Enumerator.Parseimport Data.Text.Lazy (Text, unpack)data Quote = Quote { symbol :: Text                   , date   :: Text                   , time   :: Text                   , price  :: Float}  deriving Showmain = parseFile_ "test.xml" (const Nothing) $ parseContentsparseContents = force "Missing Contents" $ tag'' "Contents" parseStockQuoteparseStockQuote = force "Missing StockQuote" $ flip (tag' "StockQuote") return $ do    s <- requireAttr "Symbol"    d <- requireAttr "Date"    t <- requireAttr "Time"    p <- requireAttr "Price"    return $ Quote s d t (read $ unpack p)