{-# LANGUAGE OverloadedStrings #-} module Books where import Control.Applicative -- base import Control.Lens -- lens import Data.Text (Text) -- text import Text.Xml.Lens -- xml-html-conduit-lens -- $setup -- >>> :set -XOverloadedStrings -- >>> import Text.Xml.Lens -- >>> import qualified Data.Text.Lazy.IO as Text -- >>> doc <- Text.readFile "example/books.xml" -- | Titles of the books in the "Textbooks" category -- -- >>> toListOf titles doc -- ["Learn You a Haskell for Great Good!","Programming in Haskell","Real World Haskell"] titles :: AsXmlDocument t => Traversal' t Text titles = xml...attributed (ix "category".only "Textbooks").node "title".text -- | Authors of the books longer then 500 pages -- -- >>> toListOf authors doc -- ["Bryan O'Sullivan, Don Stewart, and John Goerzen","Benjamin C. Pierce"] authors :: AsXmlDocument t => Traversal' t Text authors = xml...filtered (has (node "pages".text.filtered (> "500"))).node "author".text -- | Titles and authors of the books in the "Textbooks" category -- -- >>> toListOf titlesAndAuthors doc -- [("Learn You a Haskell for Great Good!","Miran Lipovaca"),("Programming in Haskell","Graham Hutton"),("Real World Haskell","Bryan O'Sullivan, Don Stewart, and John Goerzen")] titlesAndAuthors :: AsXmlDocument t => Fold t (Text, Text) titlesAndAuthors = xml...attributed (ix "category".only "Textbooks").runFold (liftA2 (,) (Fold title) (Fold author)) where title, author :: Fold Element Text title = node "title".text author = node "author".text -- | Title of the third book in the list -- -- >>> preview thirdTitle doc -- Just "Programming in Haskell" thirdTitle :: AsXmlDocument t => Fold t Text thirdTitle = xml.parts.ix 2.node "title".text -- | All tags in the document. -- -- >>> toListOf allTags doc -- ["books","book","title","author","pages","price","book","title","author","pages","book","title","author","pages","book","title","author","pages","book","title","author","pages","book","title","author","pages","book","title","author"] allTags :: AsXmlDocument t => Fold t Text allTags = xml.folding universe.name -- | Compute the length of the books list: -- -- >>> lengthOf allBooks doc -- 7 allBooks :: AsXmlDocument t => Traversal' t Element allBooks = xml.plate -- | Find the title of the first book in the "Joke" category: -- -- >>> preview titleOfFirstJokeBook doc -- Just "Functional Ikamusume" titleOfFirstJokeBook :: AsXmlDocument t => Traversal' t Text titleOfFirstJokeBook = xml...attributed (ix "category".only "Joke").node "title".text -- | Append the string " pages" to `` tags' content: -- -- >>> Text.putStr (appendPages doc) -- -- -- Haskell 98 language and libraries: the Revised Report -- Simon Peyton Jones -- 272 pages -- £45.00 -- -- -- Learn You a Haskell for Great Good! -- Miran Lipovaca -- 360 pages -- -- -- Programming in Haskell -- Graham Hutton -- 200 pages -- -- -- Real World Haskell -- Bryan O'Sullivan, Don Stewart, and John Goerzen -- 700 pages -- -- -- The Fun of Programming -- Jeremy Gibbons and Oege de Moor -- 288 pages -- -- -- Types and Programming Languages -- Benjamin C. Pierce -- 645 pages -- -- -- Functional Ikamusume -- Team "Referential Transparent Sea Keepers" -- -- appendPages :: AsXmlDocument t => t -> t appendPages = xml...node "pages".text <>~ " pages"