Here is code that will output maven coordinates from given pom.xml file. How can I remove boilerplate (possibly convert it to xml picklers)?
import Control.Lens ((&))
import Text.XML.HXT.Core
import System.Environment (getArgs)
import Text.XML.HXT.Arrow.XmlArrow
import Control.Monad (liftM)
import Data.Maybe
import Control.Applicative
main = do
(filename:_) <- getArgs
_groupId <- extractOne filename $ project >>> groupId
_artifactId <- extractOne filename $ project >>> artifactId
_version <- extractOne filename $ project >>> version
_parentGroupId <- extractOne filename $ project >>> parent >>> groupId
_parentArtifactId <- extractOne filename $ project >>> parent >>> artifactId
_parentVersion <- extractOne filename $ project >>> parent >>> version
let coordinate = (,,) <$> _groupId <*> _artifactId <*> _version
parentCoordinate = (,,) <$> _parentGroupId <*> _parentArtifactId <*> _parentVersion
in do
print coordinate
print parentCoordinate
extract :: String -> IOSArrow XmlTree a -> IO [a]
extract filename cat = runX $ readDocument [withValidate no] filename >>> cat
extractOne :: String -> IOSArrow XmlTree a -> IO (Maybe a)
extractOne filename cat = extract filename cat >>= return . listToMaybe
version :: ArrowXml a => a XmlTree String
version = getChildren >>> hasName "version" >>> getChildren >>> getText
artifactId :: ArrowXml a => a XmlTree String
artifactId = getChildren >>> hasName "artifactId" >>> getChildren >>> getText
groupId :: ArrowXml a => a XmlTree String
groupId = getChildren >>> hasName "groupId" >>> getChildren >>> getText
parent :: ArrowXml a => a XmlTree XmlTree
parent = getChildren >>> hasName "parent"
project :: ArrowXml a => a XmlTree XmlTree
project = getChildren >>> hasName "project"