如何使用html5ever解析页面,修改DOM并将其序列化?

kes*_*orn 8 rust servo html5ever

我想解析一个网页,在某些位置插入锚点并再次渲染修改后的DOM,以便为Dash生成docsets .这可能吗?

从html5ever中包含的示例中,我可以看到如何读取HTML文件并执行穷人的HTML输出,但我不明白如何修改RcDom我检索到的对象.

我想看到一个片段插入一个锚元素(<a name="foo"></a>)到一个RcDom.

注意:这是一个关于Rust和html5ever的问题......我知道如何用其他语言或更简单的HTML解析器.

ant*_*oyo 9

下面是一些解析文档的代码,为链接添加一个achor并打印新文档:

extern crate html5ever;

use html5ever::{ParseOpts, parse_document};
use html5ever::tree_builder::TreeBuilderOpts;
use html5ever::rcdom::RcDom;
use html5ever::rcdom::NodeEnum::Element;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;

fn main() {
    let opts = ParseOpts {
        tree_builder: TreeBuilderOpts {
            drop_doctype: true,
            ..Default::default()
        },
        ..Default::default()
    };
    let data = "<!DOCTYPE html><html><body><a href=\"foo\"></a></body></html>".to_string();
    let dom = parse_document(RcDom::default(), opts)
        .from_utf8()
        .read_from(&mut data.as_bytes())
        .unwrap();

    let document = dom.document.borrow();
    let html = document.children[0].borrow();
    let body = html.children[1].borrow(); // Implicit head element at children[0].

    {
        let mut a = body.children[0].borrow_mut();
        if let Element(_, _, ref mut attributes) = a.node {
            attributes[0].value.push_tendril(&From::from("#anchor"));
        }
    }

    let mut bytes = vec![];
    serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
    let result = String::from_utf8(bytes).unwrap();
    println!("{}", result);
}
Run Code Online (Sandbox Code Playgroud)

这打印出以下内容:

<html><head></head><body><a href="foo#anchor"></a></body></html>
Run Code Online (Sandbox Code Playgroud)

如您所见,我们可以通过children属性浏览子节点.

我们可以改变一个属性向量中存在的属性Element.

  • 1岁的答案,但我今天刚刚尝试了这个代码,它无法为我编译.我在Rust 1.20.0上使用最新版本的html5ever.错误是`unresolved import html5ever :: rcdom :: NodeEnum :: Element`,它说它再也找不到NodeEnum了.它被弃用了吗?我错过了什么 ? (3认同)
  • 更新的示例链接(我认为):https://github.com/servo/html5ever/blob/master/rcdom/examples/print-rcdom.rs (2认同)