我希望能够访问XML文件的数据,如
<?xml version="1.0"?>
<MY>
<Foo id="1" name="test">
<Argument name="a" />
</Foo>
<Foo id="2" name="test2">
<Argument name="a" />
<Argument name="b" />
</Foo>
<Other id="2" name="someOther"/>
</MY>
我想要,例如用它的参数读出每个Foo,我怎么能用Haskell做到这一点? (我想使用HaXml模块)
我不知道从哪里开始。
答案 0 :(得分:5)
对于简单的任务,您可能需要考虑使用tagsoup包。
答案 1 :(得分:5)
是的,文档是关于haskell的一大缺点。我想知道为什么haskell人讨厌如此记录他们的代码。不需要胖纸,很少使用例子通常绰绰有余。
此处提供的HaXML使用的小例子:http://book.realworldhaskell.org/read/extended-example-web-client-programming.html
答案 2 :(得分:3)
我无法找到haXml的最新文档和示例。
但是有一些HXT的文档可用。 我知道这可能对你的例子来说太过分了,但无论如何。
如果您想使用tagsoup,可能以下答案可能有所帮助:
xml-tree parser (Haskell) for graph-library
In Haskell how do you extract strings from an XML document?
以下是文档HXT的示例:
http://www.haskell.org/haskellwiki/HXT/Conversion_of_Haskell_data_from/to_XML
http://www.haskell.org/haskellwiki/HXT
http://www.haskell.org/haskellwiki/HXT/Practical
http://en.wikibooks.org/wiki/Haskell/XML
现在代码使用HXT。 (警告我不确定这是否正确)
我按照教程: http://www.haskell.org/haskellwiki/HXT/Conversion_of_Haskell_data_from/to_XML
您需要将xml文件作为“data.xml”
import Data.Map (Map, fromList, toList)
import Text.XML.HXT.Core
type Foos = Map String [Foo]
data Foo = Foo
{
fooId :: String
, fooName :: String
, arguments :: [Argument]
}
deriving (Show, Eq)
data Argument = Argument
{ argName :: String
}
deriving (Show, Eq)
instance XmlPickler Foo where
xpickle = xpFoo
instance XmlPickler Argument where
xpickle = xpArgument
-- WHY do we need this?? no clue
instance XmlPickler Char where
xpickle = xpPrim
-- this could be wrong
xpFoos :: PU Foos
xpFoos
= xpWrap (fromList
, toList
) $
xpList $
xpElem "MY" $
xpickle
xpFoo :: PU Foo
xpFoo
= xpElem "Foo" $
xpWrap ( uncurry3 Foo
, \ f -> (fooId f
, fooName f
, arguments f
)
) $
xpTriple (xpAttr "id" xpText)
(xpAttr "name" xpText)
(xpList xpickle)
xpArgument :: PU Argument
xpArgument
= xpElem "Argument" $
xpWrap ( \ ((a)) -> Argument a
, \ t -> (argName t)
) $
(xpAttr "name" xpText )
main :: IO ()
main
= do
runX ( xunpickleDocument xpFoos
[ withValidate no
, withTrace 1
, withRemoveWS yes
, withPreserveComment no
] "data.xml"
>>>
arrIO ( \ x -> do {print x ; return x})
)
return ()
结果(您需要xml示例为“data.xml”):
-- (1) getXmlContents
-- (1) readDocument: "data.xml" (mime type: "text/xml" ) will be processed
-- (1) readDocument: "data.xml" processed
fromList [("",[Foo {fooId = "1", fooName = "test", arguments = [Argument {argName = "a"}]},
Foo {fooId = "2", fooName = "test2", arguments = [Argument {argName = "a"},
Argument {argName = "b"}]}])]
答案 3 :(得分:1)
使用xml-conduit,您可以非常简单明了地完成:
{-# LANGUAGE OverloadedStrings #-}
import Data.Conduit
import qualified Text.XML.Stream.Parse as XP
import Data.String(fromString)
parseFile fileName = runResourceT $ XP.parseFile XP.def (fromString fn)
$$ parseXML
parseXML = XP.force $ XP.tagNoAttr "MY"
$ XP.many
$ XP.tagName "foo" (mapM XP.requiredAttr ["id", "name"])
$ \(~[i,n]) -> return (i,n)
答案 4 :(得分:0)
有一个教程introduction to haxml,我的回答有点迟了,但我认为教程描述了如何解析与您在问题中提供的XML非常相似的XML。
如何读取XML的一个非常简单的实现是:
c <- fReadXml "your.xml" :: IO ANYContent
print c