我正在解析一个XML文件,HXT我试图将一些节点提取分解为模块化部分(我一直在使用它作为我的指南).不幸的是,一旦我进行了第一级解析,我无法弄清楚如何应用一些选择器.
import Text.XML.HXT.Core
let node tag = multi (hasName tag)
xml <- readFile "test.xml"
let doc = readString [withValidate yes, withParseHTML no, withWarnings no] xml
books <- runX $ doc >>> node "book"
Run Code Online (Sandbox Code Playgroud)
我看到书有类型 [XmlTree]
:t books
books :: [XmlTree]
Run Code Online (Sandbox Code Playgroud)
现在我想得到第一个元素,books然后在子树中提取一些值.
let b = head(books)
runX $ b >>> node "cost"
Couldn't match type ‘Data.Tree.NTree.TypeDefs.NTree’
with ‘IOSLA (XIOState ()) XmlTree’
Expected type: IOSLA (XIOState ()) XmlTree XNode
Actual type: XmlTree
In the first argument of ‘(>>>)’, namely ‘b’
In the second argument of ‘($)’, namely ‘b >>> node "cost"’
Run Code Online (Sandbox Code Playgroud)
一旦我找到选择器,我就无法找到选择器,XmlTree并且我显示上述不正确的用法来说明我想要的内容.我知道我可以这样做:
runX $ doc >>> node "book" >>> node "cost" /> getText
["55.9","95.0"]
Run Code Online (Sandbox Code Playgroud)
但我不仅对cost内部还有更多的元素感兴趣book.XML文件非常深,所以我不想嵌套所有内容,<+>并且rater更喜欢提取我想要的块,然后在单独的函数中提取子元素.
示例(组成)XML文件:
<?xml version="1.0" encoding="UTF-8"?><start xmlns="http://www.example.com/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<books>
<book>
<author>
<name>
<first>Joe</first>
<last>Smith</last>
</name>
<city>New York City</city>
</author>
<released>1990-11-15</released>
<isbn>1234567890</isbn>
<publisher>X Publisher</publisher>
<cost>55.9</cost>
</book>
<book>
<author>
<name>
<first>Jane</first>
<last>Jones</last>
</name>
<city>San Francisco</city>
</author>
<released>1999-01-19</released>
<isbn>0987654321</isbn>
<publisher>Y Publisher</publisher>
<cost>95.0</cost>
</book>
</books>
</start>
Run Code Online (Sandbox Code Playgroud)
有人能帮助我理解,如何提取子元素book?理想的情况是有像你一样的东西>>>,并node让我可以定义自己的功能,如getCost,getName等每一个大致会具有签名XmlTree -> [String]
doc不是你想的那样。它有类型IOStateArrow s b XmlTree。你真的应该再次阅读你的指南,所有你想知道的都在标题“避免 IO”下结束。
箭头基本上是函数。SomeArrow a b可以被认为是 类型的广义/专用函数a -> b。>>>作用域中的其他运算符用于箭头组合,类似于函数组合。您books有类型[XmlTree],因此它不是箭头,并且不能与箭头组成。满足您的需求的是runLA,它将箭头像node "tag"普通函数一样转换:
module Main where
import Text.XML.HXT.Core
main = do
html <- readFile "test.xml"
let doc = readString [withValidate yes, withParseHTML no, withWarnings no] html
books <- runX $ doc >>> node "book"
-- runLA (node "cost" /> getText) :: XmlTree -> [String]
let costs = books >>= runLA (node "cost" /> getText)
print costs
node tag = multi (hasName tag)
Run Code Online (Sandbox Code Playgroud)