我正在尝试使用 Haskell 解析一些 XML 文件。对于这项工作我正在使用HXT http://www.haskell.org/haskellwiki/HXT获得有关现实世界应用中箭头的一些知识。所以我对箭头主题很陌生。
在 XPath 中(和HaXml http://hackage.haskell.org/packages/archive/HaXml/1.24/doc/html/Text-XML-HaXml-Combinators.html#v%3aposition)可以按位置选择节点,比方说:/root/a[2]/b
即使一遍又一遍地阅读文档后,我也不知道如何使用 HXT 做类似的事情。
这是我正在使用的一些示例代码:
module Main where
import Text.XML.HXT.Core
testXml :: String
testXml = unlines
[ "<?xml version=\"1.0\"?>"
, "<root>"
, " <a>"
, " <b>first element</b>"
, " <b>second element</b>"
, " </a>"
, " <a>"
, " <b>third element</b>"
, " </a>"
, " <a>"
, " <b>fourth element</b>"
, " <b>enough...</b>"
, " </a>"
, "</root>"
]
selector :: ArrowXml a => a XmlTree String
selector = getChildren /> isElem >>> hasName "a" -- how to select second <a>?
/> isElem >>> hasName "b"
/> getText
main :: IO ()
main = do
let doc = readString [] testXml
nodes <- runX $ doc >>> selector
mapM_ putStrLn nodes
期望的输出是:
third element
提前致谢!
我相信的解决方案选择“/root/a[2]/b”(第二个“a”标签内的所有“b”标签):
selector :: ArrowXml a => Int -> a XmlTree String
selector nth =
(getChildren /> isElem >>> hasName "a") -- the parentheses required!
>. (!! nth)
/> isElem >>> hasName "b" /> getText
(结果是["third element"]
).
说明:据我所知,class (..., ArrowList a, ...) => ArrowXml a
, so ArrowXml a
是一个子类ArrowList
。翻翻ArrowList
界面:
(>>.) :: a b c -> ([c] -> [d]) -> a b d
(>.) :: a b c -> ([c] -> d) -> a b d
so >>.
可以使用一些提升来选择列表的子集[c] -> [d]
and >.
可以使用 type 的提升函数从列表中选择单个项目[c] -> d
。因此,在选择子项并过滤标签“a”之后,让我们使用(!! nth) :: [a] -> a
.
有一个重要的事情需要注意:
infix 1 >>>
infix 5 />
infix 8 >.
(所以我很难弄清楚为什么>.
没有括号则无法按预期工作)。因此,getChildren /> isElem >>> hasName "a"
必须用括号括起来。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)