{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Main where
import Control.Applicative (optional)
import qualified Text.Show.Pretty as PP
import qualified Text.XML.Light as XML
import qualified Text.XML.Xleb as X
data Feed = Feed
{ feedTitle :: String
, feedSubtitle :: String
, feedLinks :: [Link]
, feedId :: String
, feedUpdated :: String
, feedEntries :: [Entry]
} deriving (Show)
data Link = Link
{ linkHref :: String
, linkRel :: Maybe String
} deriving (Show)
data Entry = Entry
{ entryTitle :: String
, entryLinks :: [Link]
, entryId :: String
, entryUpdated :: String
, entrySummary :: String
, entryAuthor :: Author
, entryContent :: Content
} deriving (Show)
data Content
= XHTMLContent XML.Element
| HTMLContent String
| TextContent String
deriving (Show)
data Author = Author
{ authorName :: String
, authorEmail :: String
} deriving (Show)
feed :: X.Xleb Feed
feed = X.elem "feed" $ do
feedTitle <- X.child "title" (X.contents X.string)
feedSubtitle <- X.child "subtitle" (X.contents X.string)
feedLinks <- X.children "link" link
feedId <- X.child "id" (X.contents X.string)
feedUpdated <- X.child "updated" (X.contents X.string)
feedEntries <- X.children "entry" entry
return Feed { .. }
link :: X.Xleb Link
link =
Link <$> X.attr "href" X.string
<*> optional (X.attr "rel" X.string)
entry :: X.Xleb Entry
entry = X.elem "entry" $ do
entryTitle <- X.child "title" (X.contents X.string)
entryLinks <- X.children "link" link
entryId <- X.child "id" (X.contents X.string)
entryUpdated <- X.child "updated" (X.contents X.string)
entrySummary <- X.child "summary" (X.contents X.string)
entryAuthor <- X.child "author" author
entryContent <- X.child "content" content
return Entry { .. }
content :: X.Xleb Content
content = do
typ <- X.attr "type" X.string
case typ of
"xhtml" -> XHTMLContent <$> X.rawElement
"html" -> HTMLContent <$> X.contents X.string
"text" -> TextContent <$> X.contents X.string
_ -> fail "Unknown content type"
author :: X.Xleb Author
author =
Author <$> X.child "name" (X.contents X.string)
<*> X.child "email" (X.contents X.string)
main :: IO ()
main = do
cs <- getContents
PP.pPrint (X.runXleb cs feed)