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

{-# 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文件是here
我得到了奇怪的结果,解析的文本大部分是空的,有一些零星的实际值,尽管原始的gpx文件数据都是有效的。当有一个实际值时,它只在记录的一个字段中。
我很确定我没有正确使用xml-conduitapi。我做错什么了?

最佳答案

两个问题。首先,名称空间中有一个输入错误;应该是http://www.topografix.com/GPX/1/1。其次,最后一个kleisli箭头(\e -> do -- etc.)作用于trkpt元素的子元素,而不是trkpt元素本身。这里有一个gpxTrkpts应该做你想做的事情:

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

关于xml - 如何使用Haskell的xml-conduit解析GPX文件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31897737/

10-10 03:53