1

使用 执行不区分大小写的标记和属性名称匹配的最佳方法是什么xml-conduit

例如,考虑findNodesFP Complete's School of Haskell 的 HTML 解析示例中的函数:

https://www.fpcomplete.com/school/starting-with-haskell/libraries-and-frameworks/text-manipulation/tagsoup

-- The data we're going to search for
findNodes :: Cursor -> [Cursor]
findNodes = element "span" >=> attributeIs "class" "sb_count" >=> child

(我已经修改了这一行,使其适用于 Bing 的当前页面结构。)

我的实验表明element并且attributeIs在匹配名称时不执行不区分大小写的比较。有没有简单的方法来改变这个?

4

2 回答 2

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

现在我们只在elementand中使用小写名称attributeIs

于 2014-08-16T04:42:13.777 回答
1

您可以使用laxElement在匹配元素时忽略大小写。它还将忽略名称空间。checkName编写一个具有您正在寻找的确切语义的包装器应该很容易。

于 2014-08-16T20:30:14.440 回答