Rust 如何使用HTML5解析页面、修改DOM并序列化它?

Rust 如何使用HTML5解析页面、修改DOM并序列化它?,rust,servo,html5ever,Rust,Servo,Html5ever,我想解析一个网页,在某些位置插入锚,并再次呈现修改后的DOM,以便为生成文档集。这可能吗 从html5ever中包含的示例中,我可以看到如何读取HTML文件和执行穷人的HTML输出,但我不明白如何修改检索到的RcDom对象 我希望看到一个片段将锚元素()插入到RcDom 注意:这是一个关于生锈和HTML5的问题,特别是。。。我知道如何在其他语言或更简单的HTML解析器中完成此操作。以下是一些代码,用于解析文档、向链接添加achor并打印新文档: extern crate html5ever;

我想解析一个网页,在某些位置插入锚,并再次呈现修改后的DOM,以便为生成文档集。这可能吗

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

我希望看到一个片段将锚元素(
)插入到
RcDom


注意:这是一个关于生锈和HTML5的问题,特别是。。。我知道如何在其他语言或更简单的HTML解析器中完成此操作。

以下是一些代码,用于解析文档、向链接添加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);
}
extern板条箱html5ever;
使用html5ever:{ParseOpts,parse_document};
使用html5ever::tree_builder::TreeBuilderOpts;
使用html5ever::rcdom::rcdom;
使用html5ever::rcdom::NodeEnum::Element;
使用html5ever::serialize::{SerializeOpts,serialize};
使用html5ever::tendril::TendrilSink;
fn main(){
让opts=ParseOpts{
树生成器:TreeBuilderOpts{
drop_doctype:true,
…默认值::默认值()
},
…默认值::默认值()
};
将数据“”设为字符串();
让dom=parse_文档(RcDom::default(),opts)
.from_utf8()
.read_from(&mut data.as_bytes())
.unwrap();
let document=dom.document.borrow();
让html=document.children[0].borrow();
let body=html.children[1].borrow();//子项[0]处的隐式head元素。
{
设mut a=body.children[0]。借用_mut();
如果let元素(x,x,ref mut attributes)=a.node{
属性[0].value.push_卷须(&From::From(“#锚”);
}
}
让mut bytes=vec![];
序列化(&mut bytes,&dom.document,SerializeOpts::default()).unwrap();
让结果=字符串::from_utf8(字节).unwrap();
println!(“{}”,结果);
}
这将打印以下内容:

<html><head></head><body><a href="foo#anchor"></a></body></html>

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


我们可以更改
元素的属性向量中的属性,非常感谢,这正是我所希望的。1年前的答案,但我今天刚刚尝试了这段代码,它无法为我编译。我使用的是Rust 1.20.0,使用的是最新版本的HTML5。错误是
unresolved import html5ever::rcdom::NodeEnum::Element
,它说它再也找不到NodeEnum了。它被弃用了吗?我遗漏了什么吗?看看这个例子——它使用了另一种看起来更新鲜的数据结构:更容易用更高级的语法解析HTML,而不是直接解析HTML5。