0

我正在尝试通过 selector 获取带有类 nav 的元素.nav。结果库抛出异常:

仅实现类型选择器。

代码示例:

import 'package:html5lib/parser.dart';

void main() {
  String html = '''
    <html>
    <head><title>Some title</title></head>
    <body>
    <div class="nav">Some nav content</div>
    </body>
    </html>
  ''';
  var doc = parse(html);

  print(doc.query('.nav'));
}

控制台输出:

Breaking on exception: UnimplementedError: only type selectors are implemented
Unhandled exception:
UnimplementedError: only type selectors are implemented
#0      Node._typeSelector (package:html5lib/dom.dart:269:7)
#1      Node.query (package:html5lib/dom.dart:249:62)
#2      main (/home/hello/dart/test/bin/simple_exp.dart:14:18)
#3      _startIsolate.isolateStartHandler (dart:isolate-patch/isolate_patch.dart:190)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:93)

怎么了?

4

2 回答 2

3

尚未实现完整的 CSS 选择器匹配。

根据您的用例,您可以匹配类型(标签名称),然后使用元素的类属性过滤结果。

以下是如何执行此操作的示例:

  var el = doc.queryAll('div').where((el) => 
      el.attributes.keys.contains('class') &&
        el.attributes['class'].split(' ').contains('nav')).first;

希望有人能尽快实现查询选择器匹配支持——因为这种解决方法对于具有大量 div 标签的文档非常低效。

另一种解决方案是进行自己的遍历 - 如下所示:

queryClass(Node element, String className) {
  for (var node in element.nodes) {
    if (node is! Element) continue;
    if (node.attributes.keys.contains('class') 
        && node.attributes['class'].split(' ').contains(className)) {
      return node;
    }
    var result = queryClass(node, className);
    if (result != null) return result;
  }
  return null;
}

main() {
   var doc = parse(...);
   var el = queryClass(doc, 'nav');
   print(el);
}
于 2013-12-02T04:25:38.707 回答
1

翻看html5lib解析器的代码,可以看到查询功能只对类型选择器起作用(如:div、head等)。源代码中有一条注释说明,而且抛出的异常非常明确。

对于您的情况,可能的解决方案是使用 queryAll 方法返回所有 div 并遍历它们,直到找到具有相应类的一个(或多个)。我知道这远远不是理想的解决方案,但它可能会奏效。

希望能帮助到你!

于 2013-12-01T20:35:26.240 回答