open Bytesrw (* CSS selector query example *) let html = {| Products

Product List

|} let () = let result = Html5rw.parse (Bytes.Reader.of_string html) in (* Find element by ID *) Printf.printf "=== ID Selector (#title) ===\n"; let titles = Html5rw.query result "#title" in List.iter (fun node -> Printf.printf "Found: %s\n" (Html5rw.get_text_content node) ) titles; (* Find elements by class *) Printf.printf "\n=== Class Selector (.product) ===\n"; let products = Html5rw.query result ".product" in Printf.printf "Found %d products\n" (List.length products); (* Find elements by tag *) Printf.printf "\n=== Tag Selector (span) ===\n"; let spans = Html5rw.query result "span" in Printf.printf "Found %d span elements\n" (List.length spans); (* Find with attribute presence *) Printf.printf "\n=== Attribute Presence ([data-id]) ===\n"; let with_data_id = Html5rw.query result "[data-id]" in List.iter (fun node -> match Html5rw.get_attr node "data-id" with | Some id -> Printf.printf "Found element with data-id=%s\n" id | None -> () ) with_data_id; (* Find with attribute value *) Printf.printf "\n=== Attribute Value ([data-id=\"3\"]) ===\n"; let featured = Html5rw.query result "[data-id=\"3\"]" in List.iter (fun node -> Printf.printf "Found: %s\n" (Html5rw.get_text_content node) ) featured; (* Find with multiple classes *) Printf.printf "\n=== Multiple Classes (.product.featured) ===\n"; let featured_products = Html5rw.query result ".featured" in List.iter (fun node -> Printf.printf "Featured: %s\n" (Html5rw.get_text_content node) ) featured_products; (* Check if a node matches a selector *) Printf.printf "\n=== Match Check (.featured) ===\n"; List.iter (fun node -> if Html5rw.matches node ".featured" then Printf.printf "This product is featured!\n" ) products; (* Pseudo-class: first-child *) Printf.printf "\n=== Pseudo-class (:first-child) ===\n"; let first = Html5rw.query result "li:first-child" in List.iter (fun node -> Printf.printf "First li: %s\n" (String.trim (Html5rw.get_text_content node)) ) first; (* Pseudo-class: last-child *) Printf.printf "\n=== Pseudo-class (:last-child) ===\n"; let last = Html5rw.query result "li:last-child" in List.iter (fun node -> Printf.printf "Last li: %s\n" (String.trim (Html5rw.get_text_content node)) ) last; (* Universal selector *) Printf.printf "\n=== Universal Selector (*) ===\n"; let all = Html5rw.query result "*" in Printf.printf "Total elements: %d\n" (List.length all); (* Combining queries: find products then filter *) Printf.printf "\n=== Combined: Products with price > $15 ===\n"; List.iter (fun product -> (* Find price span within this product *) let price_spans = List.filter (fun node -> Html5rw.matches node ".price" ) (Html5rw.descendants product) in List.iter (fun price_span -> let price_text = Html5rw.get_text_content price_span in (* Parse price - remove $ and convert *) let price_str = String.sub price_text 1 (String.length price_text - 1) in let price = float_of_string price_str in if price > 15.0 then begin let name_spans = List.filter (fun node -> Html5rw.matches node ".name" ) (Html5rw.descendants product) in match name_spans with | name :: _ -> Printf.printf " %s: %s\n" (Html5rw.get_text_content name) price_text | [] -> () end ) price_spans ) products