pub struct Selector { /* private fields */ }query only.Expand description
A parsed, reusable CSS selector list.
Parse once, match many times: pass &selector anywhere a selector string
is accepted (Dom::select, NodeRef::closest, …).
Supported: type, *, #id, .class, attribute selectors (=, ~=,
|=, ^=, $=, *=, with i/ s flags), selector lists, all four
combinators (descendant, >, +, ~), :first-child, :last-child,
:only-child, :nth-child(An+B [of S]), :nth-last-child(), the
*-of-type variants, :empty, :root, :scope, :not(), :is(), :where(),
:has() (relative: :has(> img), :has(+ p)), :checked, :disabled,
:enabled, CSS escapes (.md\:flex), and the non-standard jQuery-style
:contains("text") (case-sensitive substring of the text content).
Tag, attribute and pseudo-class names are ASCII case-insensitive; ids,
classes and attribute values are case-sensitive, except the values of
HTML’s enumerated attributes (type, method, dir, rel, …), which
compare case-insensitively as in browsers unless the selector says s.
Anything else (:hover, ::before, namespaces, …) is a parse error, never
silently ignored.
Sibling combinators and positional pseudo-classes count elements only.
Top-level nodes count as siblings of each other, so li + li works on a
fragment like <li>a</li><li>b</li>; each top-level element is :root.
use domtree::Selector;
let dom = domtree::parse("<ul><li class='on'>a</li><li>b</li></ul>");
let sel = Selector::parse("li:not(.on)").unwrap();
let hits: Vec<_> = dom.select(&sel).map(|n| n.text_content()).collect();
assert_eq!(hits, ["b"]);
// `FromStr` works too.
let sel: Selector = "ul > li".parse().unwrap();
assert_eq!(dom.select(&sel).count(), 2);Implementations§
Source§impl Selector
impl Selector
Sourcepub fn parse(selector: &str) -> Result<Selector, SelectorError>
pub fn parse(selector: &str) -> Result<Selector, SelectorError>
Parse a selector list such as "ul > li.active, a[href^='https:']".
Anything outside the supported grammar is an error — including
pseudo-classes this engine doesn’t implement (:hover, ::before, …),
which are rejected rather than silently ignored.
use domtree::Selector;
assert!(Selector::parse("div > p:first-child").is_ok());
let err = Selector::parse("div > p)").unwrap_err();
assert_eq!(err.position(), 7);
assert_eq!(err.to_string(), "unexpected ')' at byte 7");Sourcepub fn matches(&self, node: NodeRef<'_>) -> bool
pub fn matches(&self, node: NodeRef<'_>) -> bool
Whether node is an element matching this selector, evaluated against
the whole document node belongs to.
use domtree::Selector;
let dom = domtree::parse("<div class='card'><h2>Title</h2></div>");
let h2 = dom.find_by_tag("h2").next().unwrap();
assert!(Selector::parse(".card > h2").unwrap().matches(h2));
assert!(!Selector::parse("h2:empty").unwrap().matches(h2));