首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >图形库的xml树解析器(Haskell)

图形库的xml树解析器(Haskell)
EN

Stack Overflow用户
提问于 2011-04-11 21:46:17
回答 2查看 634关注 0票数 2

我正在编写一个用于处理图形的库。主要任务是解析xml树。这棵树看起来像

代码语言:javascript
复制
<graph nodes=4 arcs=5>
    <node id=1 />
    <node id=2 />
    <node id=3 />
    <node id=4 />
    <arc from=1 to=2 />
    <arc from=1 to=3 />
    <arc from=1 to=4 />
    <arc from=2 to=4 />
    <arc from=3 to=4 />
</graph>

存储结构:

代码语言:javascript
复制
type Id = Int

data Node = Node Id deriving (Show)
data Arc = Arc Id Id deriving (Show)

data Graph = Graph { nodes :: [Node],
             arcs  :: [Arc]}

如何将xml文件中的数据写入此结构?我不能为这种xml树编写解析器(HXT库)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-12 00:46:08

假设您将其转换为正确的XML (用引号将所有属性值括起来),则以下代码将起作用(使用xml枚举器):

代码语言:javascript
复制
{-# 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

输出:

代码语言:javascript
复制
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]}
票数 1
EN

Stack Overflow用户

发布于 2011-04-12 00:18:32

您需要使用XML库吗?对于不是真正的'tagsoup',XML库可能也同样有效,如下所示:

代码语言:javascript
复制
import Text.HTML.TagSoup
import Data.Maybe

main = do
    s <- readFile "A.dat"

    -- get a list of nodes and arcs
    let g' = catMaybes
                [ case n of
                    TagOpen "node" [(_,n)]        -> Just (Left  $ Node (read n)) 
                    TagOpen "arc"  [(_,n), (_,m)] -> Just (Right $ Arc (read n) (read m))
                    _ -> Nothing

                | n <- parseTags s ]

    -- collapse them into a graph
    let g = foldr (\n g -> case n of
                                Left  n -> g { nodes = n : nodes g }
                                Right a -> g { arcs  = a : arcs  g }
                        ) (Graph [] []) g'

    print g

运行以下命令:

代码语言:javascript
复制
> main
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]}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5622238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档