Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如何使用数据类型构造函数包装HXT中的整个匹配列表?_Xml_Haskell_Hxt - Fatal编程技术网

Xml 如何使用数据类型构造函数包装HXT中的整个匹配列表?

Xml 如何使用数据类型构造函数包装HXT中的整个匹配列表?,xml,haskell,hxt,Xml,Haskell,Hxt,我现在正在学习使用它来解析文件。一个例子是。到目前为止,我得到了以下信息: import Data.Time import Text.XML.HXT.Core data Gpx = Gpx [Trk] deriving (Show) data Trk = Trk [TrkSeg] deriving (Show) data TrkSeg = TrkSeg [TrkPt] deriving (Show) data TrkPt = TrkPt

我现在正在学习使用它来解析文件。一个例子是。到目前为止,我得到了以下信息:

import Data.Time
import Text.XML.HXT.Core

data Gpx    = Gpx [Trk]           deriving (Show)
data Trk    = Trk [TrkSeg]        deriving (Show)
data TrkSeg = TrkSeg [TrkPt]      deriving (Show)
data TrkPt  = TrkPt Double Double deriving (Show)

parseGpx =
  getChildren >>> isElem >>> hasName "gpx" >>>
  getChildren >>> isElem >>> hasName "trk" >>>
  parseGpxTrk >>> arr Gpx

parseGpxTrk = undefined
parseGpxTrkSegs = undefined
您可以看到它是不完整的,但它仍然应该进行类型检查。不幸的是,我已经遇到了一个错误:

Couldn't match type ‘Trk’ with ‘[Trk]’
Expected type: Trk -> Gpx
  Actual type: [Trk] -> Gpx
In the first argument of ‘arr’, namely ‘Gpx’
In the second argument of ‘(>>>)’, namely ‘arr Gpx’
这个错误说明我试图通过
arr Gpx
构造函数传递
parseGpxTrk
箭头中的每个匹配项,但我实际想要的是通过
arr Gpx
构造函数传递整个匹配列表


那么,我如何让
HXT
(或者通常的箭头?)通过我的
arr Gpx
构造函数将匹配项作为列表传递,而不是通过
arr Gpx
构造函数传递列表中的每个条目呢?

这是一个对我来说非常好的解决方案

{-#语言箭头#-}
导入数据,也许吧
导入文本。阅读
导入Text.XML.HXT.Core
导入控制
数据Gpx=Gpx[Trk]导出(显示)
数据Trk=Trk[TrkSeg]导出(显示)
数据TrkSeg=TrkSeg[TrkPt]导出(显示)
数据TrkPt=TrkPt双重推导(显示)
最棘手的可能是
parseTrkPt
,因为要正确地进行解析,必须将
String
s解析为
Double
,这可能会失败。我决定让它返回一个
可能是TrkPt
,然后再进一步处理:

elemsNamed::arrowxmlcat=>String->cat XmlTree XmlTree
elemsNamed name=isElem>>>hasName name
parseTrkPt::arrowxmlcat=>catxmltree(可能是TrkPt)
parseTrkPt=elemsNamed“trkpt”>>>
proc trkpt->do
lat cat XmlTree Trk
帕塞特尔克=
元素名为“trk”>>>
(getChildren>>>parseTrkSeg)>。Trk
parseGpx::ArrowXml cat=>cat XmlTree Gpx
parseGpx=
元素名为“gpx”>>>
(getChildren>>>parseTrk)>。Gpx
然后,您可以非常简单地运行它,尽管您仍然需要钻取根元素:

main::IO()
main=do
gpxs>>getChildren
>>>parseGpx
--漂亮地打印文档
表单\uGPXS$\(Gpx trks)->do
putStrLn“GPX:”
表格ukS$\(Trk segs)->do
putStrLn“\t标记:”
表格usegs$\(TrkSeg pts)->do
putStrLn“\t\tSEG:”
表格uupts$\pt->do
putStr“\t\t\t”
打印pt
诀窍是使用
arrowslist
typeclass中的方法,特别是
.
它的类型为
abc->([c]->d)->abd
。它聚合
箭头列表
中的元素,将其传递给将其转换为新类型的函数,然后在新类型
d
上输出新的
箭头列表

如果需要,您甚至可以在最后3个解析器中对其进行抽象:

nestedListParser::ArrowXml cat=>String->cat-XmlTree a->([a]->b)->cat-XmlTree b
nestedListParser名称子Parser构造函数
=elemsNamed名称
>>>(getChildren>>>子parser)
>.建造师
parseTrkSeg::(箭头XML目录,箭头列表目录)=>cat XmlTree目录
parseTrkSeg=nestedListParser“trkseg”(parseTrkPt>>.catMaybes)trkseg
parseTrk::arrowxmlcat=>catxmltree-Trk
parseTrk=nestedListParser“trk”parseTrkSeg trk
parseGpx::ArrowXml cat=>cat XmlTree Gpx
parseGpx=nestedListParser“gpx”parseTrk gpx

如果您想完成GPX文件的其余语法,这可能很有用。

如果您想对GPX文件的完整语法建模,您可以使用
XmlPickler
来完成此操作,因为
XmlPickler
的设计目的是不忽略额外的内容。如果您不需要文件中的所有信息,还有其他方法,但如果您愿意,我可以举一个例子,使用
XmlPickler
作为答案,只使用您在数据类型中定义的GPX语法的子集。实际上,我可以按原样编译您的代码。我必须在
arrowxmlcat=>catxmltreegpx
parseGpx
上添加一个类型签名,但它似乎对我来说效果很好。但为什么GHC错误地推断了类型?这是GHC错误吗?这是否意味着我的代码实际上是正确的?我打算拿回一个Gpx[Trk]。@bheklillr如果可能的话,我想使用原语而不是pickler。我希望在这一点上,有人可以完成基本的代码,为我演示如何实际实现它
HXT
sure是一种神秘的、缺乏文献记载的野兽。就是它!正如你所指出的,诀窍是
.
,这是我以前从未知道的。非常感谢您解决这个问题。@Ana特别是您对
箭头列表中的函数感兴趣,其中有一些函数非常有用。我还将
>.
catMaybes
一起使用,因为它旨在转换整个列表,保留
箭头列表的结构。还有一些其他有用的组合符,您可能会发现它们对将来的解析很有用。