これを適切なXMLに変換すると仮定すると(すべての属性値を引用符で囲みます)、次のコードが機能します(xml-enumeratorを使用)。
{-# LANGUAGE OverloadedStrings #-}
import Text.XML.Enumerator.Parse
import Control.Monad
import Data.Text (unpack)
import Control.Applicative
type Id = Int
data Node = Node Id deriving (Show)
data Arc = Arc Id Id deriving (Show)
data Graph = Graph { nodes :: [Node],
arcs :: [Arc]}
deriving Show
main = parseFile_ "graph.xml" decodeEntities $ force "graph required" parseGraph
parseGraph = tagName "graph" getCounts $ \(nodeCount, arcCount) -> do
nodes <- replicateM nodeCount parseNode
arcs <- replicateM arcCount parseArc
return $ Graph nodes arcs
where
requireNum name = do
x <- requireAttr name
case reads $ unpack x of
(i, _):_ -> return i
_ -> fail $ "Invalid integer: " ++ unpack x
getCounts = do
n <- requireNum "nodes"
a <- requireNum "arcs"
return (n, a)
parseNode = force "node required" $ tagName "node"
(Node <$> requireNum "id") return
parseArc = force "arc required" $ tagName "arc"
(Arc <$> requireNum "from" <*> requireNum "to") return
出力:
Graph {nodes = [Node 1,Node 2,Node 3,Node 4], arcs = [Arc 1 2,Arc 1 3,Arc 1 4,Arc 2 4,Arc 3 4]}