The Dormouse's story
Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well.
...
"#; # fn main() {} ``` First let's try searching for a tag with a specific name: ``` # extern crate soup; # const THREE_SISTERS: &'static str = r#" #The Dormouse's story
# #Once upon a time there were three little sisters; and their names were # Elsie, # Lacie and # Tillie; # and they lived at the bottom of a well.
# #...
# "#; # fn main() { use soup::prelude::*; let soup = Soup::new(THREE_SISTERS); let title = soup.tag("title").find().expect("Couldn't find tag 'title'"); assert_eq!(title.display(), "The Dormouse's story
"# ); assert_eq!(p.get("class"), Some("title".to_string())); # } ``` So we see that `.find` will give us the first element that matches the query, and we've seen some of the methods that we can call on the results. But what if we want to retrieve more than one element with the query? For that, we'll use `.find_all`: ``` # extern crate soup; # use soup::prelude::*; # const THREE_SISTERS: &'static str = r#" #The Dormouse's story
# #Once upon a time there were three little sisters; and their names were # Elsie, # Lacie and # Tillie; # and they lived at the bottom of a well.
# #...
# "#; # fn main() { # let soup = Soup::new(THREE_SISTERS); // .find returns only the first 'a' tag let a = soup.tag("a").find().expect("Couldn't find tag 'a'"); assert_eq!( a.display(), r#"Elsie"# ); // but .find_all will return _all_ of them: let a_s = soup.tag("a").find_all(); assert_eq!( a_s.map(|a| a.display()) .collect::The Dormouse's story
# #Once upon a time there were three little sisters; and their names were # Elsie, # Lacie and # Tillie; # and they lived at the bottom of a well.
# #...
# "#; # fn main() { # let soup = Soup::new(THREE_SISTERS); let expected = [ "http://example.com/elsie", "http://example.com/lacie", "http://example.com/tillie", ]; for (i, link) in soup.tag("a").find_all().enumerate() { let href = link.get("href").expect("Couldn't find link with 'href' attribute"); assert_eq!(href, expected[i].to_string()); } # } ``` The top-level structure we've been working with here, `soup`, implements the same methods that the query results do, so you can call the same methods on it and it will delegate the calls to the root node: ``` # extern crate soup; # use soup::prelude::*; # const THREE_SISTERS: &'static str = r#" #The Dormouse's story
# #Once upon a time there were three little sisters; and their names were # Elsie, # Lacie and # Tillie; # and they lived at the bottom of a well.
# #...
# "#; # fn main() { # let soup = Soup::new(THREE_SISTERS); let text = soup.text(); assert_eq!( text, r#"The Dormouse's story The Dormouse's story Once upon a time there were three little sisters; and their names were Elsie, Lacie and Tillie; and they lived at the bottom of a well. ... "# ); # } ``` You can use more than just strings to search for results, such as Regex: ```rust # extern crate regex; # extern crate soup; # use soup::prelude::*; # use std::error::Error; use regex::Regex; # fn main() -> Result<(), Boxsome text, Some bold text
"#); let results = soup.tag(Regex::new("^b")?) .find_all() .map(|tag| tag.name().to_string()) .collect::some text, Some bold text
"#); let results = soup.tag(true) .find_all() .map(|tag| tag.name().to_string()) .collect::some text, Some bold text
"#); let b = soup.tag("b") .find() .expect("Couldn't find tag 'b'"); let p = b.parent() .expect("Couldn't find parent of 'b'"); assert_eq!(p.name(), "p".to_string()); let body = p.parent() .expect("Couldn't find parent of 'p'"); assert_eq!(body.name(), "body".to_string()); # Ok(()) # } ``` Or you can descend it: ```rust # extern crate soup; # use soup::prelude::*; # use std::error::Error; # fn main() -> Result<(), Box- ONE
- TWO
- THREE
- ONE
- TWO
- THREE