如何使用Haskell的xml管道解析GPX文件? [英] How to parse GPX file using Haskell's xml-conduit?

查看:63
本文介绍了如何使用Haskell的xml管道解析GPX文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 xml-conduit 解析GPX文件.到目前为止,我有以下内容:

I'd like to use xml-conduit to parse GPX files. So far I've got the following:

{-# 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文件数据都是有效的,但分析的文本大部分为空,具有一些零星的实际值.当有实际值时,它仅在记录的一个字段中.

I'm getting strange results where the parsed text is mostly empty, with some sporadic actual values, although the original GPX file data is all valid. When there is an actual value, it is only in one of the fields of the record.

我敢肯定我没有正确使用 xml-conduit API.我在做什么错了?

I'm quite certain I'm not using the xml-conduit API properly. What am I doing wrong?

推荐答案

两个问题.首先,名称空间中有一个错字.它应该是 http://www.topografix.com/GPX/1/1 .其次,您最后的Kleisli箭头( \ e->做-等等)作用在 trkpt 元素的子元素上,而不是作用在 trkpt上自己.这是一个 gpxTrkpts ,它应该执行您想要的操作:

Two issues. Firstly, there is a typo in the namespace; it should be http://www.topografix.com/GPX/1/1. Secondly, your final Kleisli arrow (\e -> do -- etc.) is acting on the children of the trkpt elements, rather than on the trkpt themselves. Here is a gpxTrkpts which should do what you want:

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

这篇关于如何使用Haskell的xml管道解析GPX文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆