使用xml-conduit
执行不区分大小写的标记和属性名称匹配的最佳方法是什么?
例如,考虑FP Complete的Haskell学校的HTML解析示例中的findNodes
函数:
-- The data we're going to search for
findNodes :: Cursor -> [Cursor]
findNodes = element "span" >=> attributeIs "class" "sb_count" >=> child
(我已将此行修改为可以使用Bing的当前页面结构。)
我的实验表明,element
和attributeIs
在匹配名称时不会执行不区分大小写的比较。有没有一种简单的方法来改变它?
答案 0 :(得分:1)
我找到了解决办法......仍然对清洁解决方案感兴趣。
基本上我们只创建自己的Text.HTML.DOM
版本,它在创建XML树之前修复标记事件流中的标记和属性名称。
函数eventConduit
的开头如下:
eventConduit :: Monad m => Conduit S.ByteString m XT.Event
eventConduit =
TS.tokenStream =$= go []
where
go stack = do
mx <- await
case fmap (entities . fmap' (decodeUtf8With lenientDecode)) mx of
Nothing -> closeStack stack
...
我们将case fmap ...
行更改为:
case fmap (entities . fixNames . fmap' (decodeUtf8With lenientDecode)) mx of
其中fixNames
定义为:
fixNames :: TS.Token' Text -> TS.Token' Text
fixNames (TS.TagOpen x pairs b) = TS.TagOpen (T.toLower x) (map (T.toLower *** id) pairs) b
fixNames (TS.TagClose x) = TS.TagClose (T.toLower x)
fixNames t = t
现在我们只在element
和attributeIs
中使用小写名称。
答案 1 :(得分:1)
您可以使用laxElement在匹配元素时忽略大小写。它还将忽略名称空间。编写一个包含checkName
的包装器应该很容易,它具有您正在寻找的确切语义。