到目前为止,我使用Haskell XML工具包HXT看到的所有示例都runX
用于执行解析器.runX
在IO monad中运行.有没有办法在IO之外使用这个XML解析器?对我来说似乎是一个纯粹的操作,不明白为什么我被迫在IO里面.
我认为HXT是Haskell中的XML/HTML处理库,它具有非常灵活和强大的方法,可以通过Arrows遍历和操作DOM树. http://adit.io/posts/2012-04-14-working_with_HTML_in_haskell.html
但是,似乎HXT只有DOM节点内容的String表示. http://hackage.haskell.org/packages/archive/hxt/9.1.6/doc/html/Text-XML-HXT-DOM-TypeDefs.html#t:XNode
是否可以使用ByteString或Text for HXT?文本是首选,因为我使用HXT与Yesod,似乎主要使用文本.
我正在尝试与Haskell的XML工具箱(HXT)达成协议,我正在某个地方撞墙,因为我似乎并不完全掌握箭头作为计算工具.
这是我的问题,我希望使用GHCi会话更好地说明:
> let parse p = runLA (xread >>> p) "<root><a>foo</a><b>bar</b><c>baz</c></root>"
> :t parse
parse :: LA XmlTree b -> [b]
Run Code Online (Sandbox Code Playgroud)
所以Parse是一个小帮助函数,它将我给它的任何箭头应用于普通的XML文档
<root>
<a>foo</a>
<b>bar</b>
<c>baz</c>
</root>
Run Code Online (Sandbox Code Playgroud)
我定义了另一个辅助函数,这次是在具有给定名称的节点下提取文本:
> let extract s = getChildren >>> isElem >>> hasName s >>> getChildren >>> getText
> :t extract
extract :: (ArrowXml cat) =>
String -> cat (Data.Tree.NTree.TypeDefs.NTree XNode) String
> parse (extract "a" &&& extract "b") -- extract two nodes' content.
[("foo","bar")]
Run Code Online (Sandbox Code Playgroud)
在这个函数的帮助下,很容易使用&&&
组合子来配对两个不同节点的文本,然后将它传递给构造函数,如下所示:
> parse (extract "a" …
Run Code Online (Sandbox Code Playgroud) 给出一个示例xml文件:
<root>
<tag attr="value">Content</tag>
<tag attr="value2">Content</tag>
</root>
Run Code Online (Sandbox Code Playgroud)
我如何tag
用不同的标签替换每个,所以我得到一个不同的文件:
<root>
<tag2 attr2="value"/>
<tag2 attr2="value2"/>
</root>
Run Code Online (Sandbox Code Playgroud)
文档[1]似乎使用过滤器,有没有办法用箭头单独完成这个?
我现在可以替换这样的节点:
runX $ readDocument [] "in.xml"
>>> processTopDown(
(eelem "tag2" += sattr "attr2" "XXX" )
`when` (isElem >>> hasName "tag") )
>>> writeDocument [] "test.xml"
Run Code Online (Sandbox Code Playgroud)
但我不知道如何正确地获得属性.
[1] http://www.haskell.org/haskellwiki/HXT#Transform_external_references_into_absolute_reference
我想知道在Haskell中处理Unicode XML的官方解决方案是什么.我注意到HXT使用简单的String
表示(Unicode字符列表!!!)来表示文本.
Constructors
XText String ordinary text (leaf)
XBlob Blob text represented more space efficient as bytestring (leaf)
Run Code Online (Sandbox Code Playgroud)
解析时如何在两种表示形式之间做出选择?强制用户使用字符列表听起来不是特别有吸引力的功能,特别是如果XML文档具有大量文本内容.
另外,我在Google上找到了http://hackage.haskell.org/package/hxt-unicode,但我不确定它是如何用于解析的.对Unicode的支持过去也更加明确:http://hackage.haskell.org/packages/archive/hxt/8.5.2/doc/html/Text-XML-HXT-DOM-Unicode.html 但是这个模块已经删除了最新版本(撰写本文时为9.3.1.0),没有明确的理由.那背后的动机是什么?
有人可以提供一些示例代码,也就是说如何使用HXT?维基页面在这方面严重缺乏.谢谢.
我正在尝试解析XML,但我想过滤和提取给定节点中确定数量的子节点.例如:
<root>
<node id="a" />
<node id="b" />
<node id="c" />
<node id="d" />
</root>
Run Code Online (Sandbox Code Playgroud)
然后,如果我执行箭头getChildren >>> myFilter 2
,我将只返回ID为"a"和"b"的节点.
直觉让我应该用状态箭来跟踪,但我不知道该怎么做.
我试着自己做,但这不是我想要的,看起来不是很优雅,也不行.我尝试运行我的箭头链runSLA
和一个整数参数作为初始状态,然后定义:
takeOnly :: IOSLA Int XmlTree XmlTree
takeOnly = changeState (\s b -> s-1)
>>> accessState (\s b -> if s >= 0 then b else Nothing)
Run Code Online (Sandbox Code Playgroud)
但当然我无法返回Nothing
,我需要返回一个XmlTree.但我根本不想回报任何东西!
可能有更好的方法.你能帮助我吗?
感谢您的时间和帮助!
也许我正在以错误的方式解决这个问题,但我正在使用HXT来读取我想在HOpenGL中的数组中使用的一些顶点数据.顶点数组需要是一个通过调用newArray创建的Ptr.不幸的是newArray返回IO Ptr,所以我不确定如何在Arrow中使用它.我想我需要类似于IO的类型声明 - >箭头a?
对于我使用hxt的工作,我实现了以下功能:
-- | Construction of a 8 argument arrow from a 8-ary function. Same
-- implementation as in @Control.Arrow.ArrowList.arr4@.
arr8 :: ArrowList a => (b1 -> b2 -> b3 -> b4 -> b5 -> b6 -> b7 -> b8 -> c)
-> a (b1, (b2, (b3, (b4, (b5, (b6, (b7, b8))))))) c
arr8 f = arr ( \ ~(x1, ~(x2, ~(x3, ~(x4, ~(x5, ~(x6, ~(x7, x8)))))))
-> f x1 x2 x3 x4 x5 x6 x7 x8 )
Run Code Online (Sandbox Code Playgroud)
正如在haddock注释中提到的,上面的函数 …
我正在解析一个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 …
Run Code Online (Sandbox Code Playgroud) haskell ×10
hxt ×10
arrows ×3
xml ×3
bytestring ×1
monads ×1
opengl ×1
state ×1
text ×1
tuples ×1
unicode ×1
validation ×1
web-scraping ×1
xsd ×1