1

I have this example HTML which I want to parse with kuchiki:

<a href="https://example.com"><em>@</em>Bananowy</a>

I want only Bananowy without @.

A similar question for JavaScript: How to get the text node of an element?

4

1 回答 1

1

首先,让我们从解析器如何解析开始:

    <a href="https://example.com"><em>@</em>Bananowy</a>

成一棵树。见下图:

在此处输入图像描述

现在,如果您尝试做显而易见的事情并调用anchor.text_contents(),您将获得锚标记 ( <a>) 的所有文本节点后代的所有文本内容。这就是 text_contents 根据 CSS 定义的行为方式。

但是,你只想得到"Bananowy"你有几种方法来做到这一点:

extern crate kuchiki;

use kuchiki::traits::*;

fn main() {
    let html = r"<a href='https://example.com'><em>@</em>Bananowy</a>";

    let document = kuchiki::parse_html().one(html);

    let selector = "a";
    let anchor = document.select_first(selector).unwrap();
    // Quick and dirty hack
    let last_child = anchor.as_node().last_child().unwrap();
    println!("{:?}", last_child.into_text_ref().unwrap());

    // Iterating solution
    for children in anchor.as_node().children() {
        if let Some(a) = children.as_text() {
            println!("{:?}", a);
        }
    }

    // Iterating solution - Using `text_nodes()` iterators
    anchor.as_node().children().text_nodes().for_each(|e| {
        println!("{:?}", e);
    });

    // text1 and text2 are examples how to get `String`
    let text1 = match anchor.as_node().children().text_nodes().last() {
        Some(x) => x.as_node().text_contents(),
        None => String::from(""),
    };

    let text2 = match anchor.as_node().children().text_nodes().last() {
        Some(x) => x.borrow().clone(),
        None => String::from(""),
    };
}

第一种方式是脆弱的,骇人听闻的方式。您需要意识到的是,这"Bananowy"是您的锚标记的last_childanchor.as_node().last_child().unwrap().into_text_ref().unwrap() ,并相应地获取它。

第二种解决方案是遍历锚标记的子项(即)并使用(方法)[Tag(em), TextNode("Bananowy")]仅选择文本节点。as_text()我们使用as_text()返回None所有Nodes非的方法来做到这一点TextNode。这比第一个解决方案要脆弱得多,如果你有<a><em>@</em>Banan<i>!</i>owy</a>.

编辑:

首选解决方案

环顾四周后,我找到了解决您问题的更好方法。它被称为TextNodes 迭代器

考虑到这一点,只需编写anchor.as_node().children().text_nodes().<<ITERATOR CODE GOES HERE>>;然后映射或操作您认为合适的条目。

为什么这个解决方案更好?它更简洁,它使用了老式的Iterator,所以它与您在上面给出的 JS 中的答案非常相似。

于 2019-12-24T16:15:37.667 回答