首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Haskell的xml-导管解析GPX文件?

如何使用Haskell的xml-导管解析GPX文件?
EN

Stack Overflow用户
提问于 2015-08-08 19:29:54
回答 2查看 225关注 0票数 3

我想使用xml-conduit来解析GPX文件。到目前为止,我得到了以下信息:

代码语言:javascript
运行
复制
{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative
import Data.Text           as T
import Text.XML
import Text.XML.Cursor

data Trkpt = Trkpt {
  trkptLat :: Text,
  trkptLon :: Text,
  trkptEle :: Text,
  trkptTime :: Text
  } deriving (Show)

trkptsFromFile path =
  gpxTrkpts . fromDocument <$> Text.XML.readFile def path

gpxTrkpts =
  child >=> element "{http://www.topografix.com/GPX/1/0}trk" >=>
  child >=> element "{http://www.topografix.com/GPX/1/0}trkseg" >=>
  child >=> element "{http://www.topografix.com/GPX/1/0}trkpt" >=>
  child >=> \e -> do
    let ele  = T.concat $ element "{http://www.topografix.com/GPX/1/0}ele" e >>= descendant >>= content
    let time = T.concat $ element "{http://www.topografix.com/GPX/1/0}time" e >>= descendant >>= content
    let lat  = T.concat $ attribute "lat" e
    let lon  = T.concat $ attribute "lon" e
    return $ Trkpt lat lon ele time

一个示例GPX文件是这里

我得到了一些奇怪的结果,解析的文本大部分是空的,带有一些零星的实际值,尽管原始的GPX文件数据都是有效的。当有一个实际值时,它只存在于记录的一个字段中。

我很确定我没有正确地使用xml-conduit API。我做错了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-08 20:58:27

两个问题。首先,名称空间中有一个错误;它应该是http://www.topografix.com/GPX/1/1。其次,您的最后一个Kleisli箭头(\e -> do -- etc.)是针对trkpt元素的子元素,而不是针对trkpt本身的。下面是一个gpxTrkpts,它应该做您想做的事情:

代码语言:javascript
运行
复制
gpxTrkpts =
  child >=> element "{http://www.topografix.com/GPX/1/1}trk" >=>
  child >=> element "{http://www.topografix.com/GPX/1/1}trkseg" >=>
  child >=> element "{http://www.topografix.com/GPX/1/1}trkpt" >=>
  \e -> do
    let cs = child e
        ele  = T.concat $ cs >>= element "{http://www.topografix.com/GPX/1/1}ele" >>= descendant >>= content
        time = T.concat $ cs >>= element "{http://www.topografix.com/GPX/1/1}time" >>= descendant >>= content
        lat  = T.concat $ attribute "lat" e
        lon  = T.concat $ attribute "lon" e
    return $ Trkpt lat lon ele time
票数 2
EN

Stack Overflow用户

发布于 2015-08-08 21:44:30

@duplode指出了这个问题。以下是一些更多的评论。

  1. 使用gpx-导管包怎么样?
  2. 下面是一些可以帮助调试解析问题的代码:

代码:

代码语言:javascript
运行
复制
{-# LANGUAGE OverloadedStrings #-}
module Lib2 where

import qualified Data.Text           as T
import Data.Text (Text)
import Text.XML
import Text.XML.Cursor
import qualified Filesystem.Path.CurrentOS as Path
import Control.Monad

showNode (NodeElement e)     = "NodeEement " ++ T.unpack (nameLocalName $ elementName e)
showNode (NodeInstruction _) = "NodeInstruction ..."
showNode (NodeContent t)     = "NodeContent " ++ show t
showNode (NodeComment _)     = "NodeComment"

testParser parser =  do
  content <- Text.XML.readFile def (Path.decodeString "sample.xml")
  let nodes = map node $ parser (fromDocument content)
  forM_ nodes $ \n -> putStrLn (showNode n)

在ghci中像这样使用它:

代码语言:javascript
运行
复制
ghci> :set -XOverloadedStrings
ghci> :l Lib2
Lib2> testParser child
NodeContent "\n  "
NodeEement metadata
NodeContent "\n  "
NodeEement trk
NodeContent "\n  "
NodeEement extensions
NodeContent "\n"

Lib2> testParser $ child >=> element "trk"
Lib2> testParser $ child >=> laxElement "trk"
NodeEement trk

Lib2> testParser $ child >=> laxElement "trk" >=> child >=> laxElement "trkseg"
NodeElement trkseg
Lib2> testParser $ child >=> laxElement "trk" >=> child >=> laxElement "trkseg" >=> child >=> laxElement "trkpt"
NodeEement trkpt
NodeEement trkpt
NodeEement trkpt
NodeEement trkpt
Lib2>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31897737

复制
相关文章

相似问题

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