- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我使用 XML-conduit 构建了一个 GPX 解析器并且在识别元素和跳过不需要的标签时遇到了过于冗长和脆弱的代码问题。
识别元素(一个小麻烦)
我通过仅比较 nameLocalName
来明确忽略 namespace 。我想正确的方法是将正确的命名空间硬编码到程序中,并让助手构造我的元素名称以便在 tag*
函数中进行比较?这有点烦人,因为我必须支持至少两个不同的 namespace (GPX 1.1 和 1.0),它们非常相似,我的使用不需要更改代码。
跳过元素
GPX 较大,自定义扩展集较大。因为我正在构建的工具需要的信息有限,所以我决定忽略特定标签及其所有子元素。例如:
<trkpnt lat="45.19843" lon="-122.428">
<ele>4</ele>
<time>...</time>
<extensions>
...
</extensions>
</trkpnt>
为了忽略 extensions
和带有大量子元素的类似标签,我制作了一个接收器,它会消耗元素直到结束元素 Event
:
skipTagAndContents :: (MonadThrow m) => Text -> Sink Event m (Maybe ())
skipTagAndContents n = tagPredicate ((== n) . nameLocalName)
ignoreAttrs
(const $ many (skipElements n) >> return ())
skipElements t = do
x <- await
case x of
Just (EventEndElement n) | nameLocalName n == t -> Done x Nothing
Nothing -> Done x Nothing
_ -> return (Just ())
似乎应该有一个 tag*
变体可以为我做这件事(在没有所有 child 被消耗的情况下成功)但是没有这个事实表明我缺少一个简单的组合器或者应该发送补丁 - 这是什么?
最佳答案
如果您根本不使用命名空间,使用 Data.Conduit.List.map stripNamespace
之类的东西将它们完全剥离可能是最简单的。
坦率地说,我并没有真正使用自己经常使用的流媒体界面;我几乎所有的工作都涉及 DOM (Text.XML
) 或游标界面。所以完全有可能缺少组合器。但在这种情况下,我相信您可以大大简化实现,因为 tagPredicate
不应允许内部 Sink
读取元素末尾之后的内容。所以你可以重写 skipTagAndContents
为:
tagPredicate ((== n) . nameLocalName) ignoreAttrs (const Data.Conduit.List.sinkNull)
你应该在把它放进去之前测试一下,我可能会错误地记住流接口(interface)的一些细节。
关于xml - 使用 xml-conduit 的脆弱和冗长的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10875179/
我正在努力通过 xml-conduit 将响应从 http-conduit 转换为 XML 文档。 doPost函数接受一个 XML 文档并将其发布到服务器。服务器使用 XML 文档进行响应。 doP
我有一个函数f :: ByteString -> String ,并且需要一个 Sink ByteString (ResourceT IO) . 我怎么得到这个? 不幸的是,这些文档不是很有帮助...
{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, ScopedTypeVariables #-} module Db ( couchTes
我正在尝试使用 HTTPS 从网站抓取数据。我成功地使用 Network.HTTP.Conduit 发出基本请求(发布凭据等),但未能从响应 header 中提取 cookie 信息(Set-Cook
如何使用 conduit 的库保存文件?我查看了 conduit 的教程,但似乎找不到任何东西,这是我的用例: main :: IO () main = do xxs (readFile fi
使用管道,给定: Prelude> :t (yieldMany [1..10] .| mapC show .| mapC print .| sinkList) (yieldMany [1..10] .
我试图了解如何捕获管道内引发的错误。我相信通过在管道上应用 catchC,我可以生成一个新的管道,该管道将在发生故障时重新运行。 在下面的示例中,我们有一个源,根据 bool 值,该源将抛出自定义虚拟
是否可以在 Conduit 中构建一个函数(比如 zipC2)来转换以下源: series1 = yieldMany [2, 4, 6, 8, 16 :: Int] series2 = yieldMa
我正在尝试写一个 Conduit使用 attoparsec解析器。具体来说,给定 parseOne :: Parser T , 我想构建一个 Conduit ByteString m T重复地将解析器
我有一个 conduit管道处理长文件。我想每 1000 条记录为用户打印一份进度报告,所以我写了这个: -- | Every n records, perform the IO action. --
我想计算http post body的哈希值并在接收时同时解析它,所以我需要这样的函数: unionSinks :: Monad m => Consumer a m r1 -> Consumer a
我使用 XML-conduit 构建了一个 GPX 解析器并且在识别元素和跳过不需要的标签时遇到了过于冗长和脆弱的代码问题。 识别元素(一个小麻烦) 我通过仅比较 nameLocalName 来明确忽
我想使用 xml-conduit , 具体来说 Text.XML.Stream.Parse为了从大型 XML 文件中延迟提取对象列表。 作为测试用例,我使用 the recently re-relea
我正在解析来自 http://hackage.haskell.org/package/xml-conduit-1.1.0.9/docs/Text-XML-Stream-Parse.html 的修改后的
我在使用管道库逐行拆分文本时遇到了一些麻烦。 不幸的是,我正在使用的源数据与行尾极其不一致,其中包含 \r\n和 \n序列在同一个文件中。 我找到了 lines函数在 Data.Conduit.Bin
在 Haskell 中,我正在通过管道处理一些数据。在该处理过程中,我想有条件地将数据存储在 S3 中。是否有任何 S3 库可以让我执行此操作?实际上,我想要做的是“tee”由管道创建的管道,并将其包
与 sourceFile我们得到一个 ByteString 流。 引用我的另一个问题"Combining multiple Sources/Producers into one" , 我能够使用 Zi
我想学习这个概念,以便能够理解和使用 machines 等库。 . 我试着关注 Rúnar Bjarnason's talk on machines ,但是资料太少,基本上就是一堆数据类型。我什至无法
我承认,鉴于我有限的 Haskell 知识,我并不是很了解 Conduits。如果有人可以指导我如何完成这项任务,我将不胜感激:我想获取 rawQuery 操作的输出并将其存储在一个变量中,然后我可以
我有一个简单的应用程序,它发送 HTTP(s) 请求并打印返回的数据: import Network.HTTP.Conduit (simpleHttp) simpleHttp "http://exam
我是一名优秀的程序员,十分优秀!