PureHTML.Query (PureHTML v0.4.0)

View Source

CSS selector querying for PureHTML documents.

Provides functions for finding and traversing HTML nodes using CSS selectors.

Summary

Functions

Extracts an attribute value from a single node.

Extracts attribute values from a list of nodes.

Finds elements matching a selector and extracts an attribute from them.

Returns the immediate children of a node.

Finds all nodes matching the CSS selector.

Finds the first node matching the CSS selector.

Extracts text content from an HTML tree or node.

Types

html_node()

@type html_node() ::
  {String.t(), [{String.t(), String.t()}], [html_node() | String.t()]}
  | String.t()
  | {:comment, String.t()}
  | {:doctype, String.t(), String.t() | nil, String.t() | nil}

html_tree()

@type html_tree() :: [html_node()]

Functions

attr(node, name)

@spec attr(html_node(), String.t()) :: String.t() | nil

Extracts an attribute value from a single node.

Returns the attribute value as a string, or nil if the attribute doesn't exist or the input is not an element.

Examples

iex> node = {"a", [{"href", "/home"}, {"class", "link"}], ["Home"]}
iex> PureHTML.attr(node, "href")
"/home"

iex> node = {"a", [{"href", "/home"}], ["Home"]}
iex> PureHTML.attr(node, "title")
nil

attribute(html, name)

@spec attribute(html_tree() | html_node(), String.t()) :: [String.t()]

Extracts attribute values from a list of nodes.

Returns a list of attribute values. Nodes without the attribute are skipped.

Examples

iex> "<a href='/one'>One</a><a href='/two'>Two</a>"
...> |> PureHTML.parse()
...> |> PureHTML.query("a")
...> |> PureHTML.attribute("href")
["/one", "/two"]

attribute(html, selector, name)

@spec attribute(html_tree() | html_node(), String.t(), String.t()) :: [String.t()]

Finds elements matching a selector and extracts an attribute from them.

Combines find/2 and attribute/2 into a single call for convenience.

Examples

iex> "<nav><a href='/'>Home</a><a href='/about'>About</a></nav>"
...> |> PureHTML.parse()
...> |> PureHTML.attribute("a", "href")
["/", "/about"]

iex> "<div><img src='a.png'><img src='b.png'></div>"
...> |> PureHTML.parse()
...> |> PureHTML.attribute("img", "src")
["a.png", "b.png"]

children(node, opts \\ [])

@spec children(
  html_node(),
  keyword()
) :: html_tree() | nil

Returns the immediate children of a node.

Options

  • :include_text - Include text nodes (default: true)

Examples

iex> node = {"div", [], [{"p", [], ["Hello"]}, "Some text"]}
iex> PureHTML.Query.children(node)
[{"p", [], ["Hello"]}, "Some text"]

iex> node = {"div", [], [{"p", [], ["Hello"]}, "Some text"]}
iex> PureHTML.Query.children(node, include_text: false)
[{"p", [], ["Hello"]}]

find(html, selector)

Finds all nodes matching the CSS selector.

Supported Selectors

  • Tag: div, p, a
  • Universal: *
  • Class: .class
  • ID: #id
  • Attribute: [attr], [attr=value], [attr^=prefix], [attr$=suffix], [attr*=substring]
  • Combinators: div p (descendant), div > p (child), h1 + p (adjacent sibling), h1 ~ p (general sibling)
  • Selector list: .a, .b

Examples

iex> html = PureHTML.parse("<div><p class='intro'>Hello</p><p>World</p></div>")
iex> PureHTML.Query.find(html, "p.intro")
[{"p", [{"class", "intro"}], ["Hello"]}]

iex> html = PureHTML.parse("<ul><li>A</li><li>B</li></ul>")
iex> PureHTML.Query.find(html, "li")
[{"li", [], ["A"]}, {"li", [], ["B"]}]

find_one(html, selector)

Finds the first node matching the CSS selector.

Returns the first matching node, or nil if no match is found. More efficient than find/2 when you only need the first result.

Examples

iex> "<ul><li>A</li><li>B</li></ul>"
...> |> PureHTML.parse()
...> |> PureHTML.query_one("li")
{"li", [], ["A"]}

iex> "<div><p>Hello</p></div>"
...> |> PureHTML.parse()
...> |> PureHTML.query_one(".missing")
nil

text(html, opts \\ [])

@spec text(
  html_tree() | html_node(),
  keyword()
) :: String.t()

Extracts text content from an HTML tree or node.

Options

  • :deep - Traverse all descendants (default: true). When false, only direct text children.
  • :separator - String to insert between text segments (default: "")
  • :strip - Strip whitespace from each segment and remove empty segments (default: false)
  • :include_script - Include text from <script> tags (default: false)
  • :include_style - Include text from <style> tags (default: false)
  • :include_inputs - Include value from <input> and <textarea> (default: false)

Examples

iex> html = PureHTML.parse("<p>Hello <strong>World</strong></p>")
iex> PureHTML.text(html)
"Hello World"

iex> html = PureHTML.parse("<ul><li>A</li><li>B</li></ul>")
iex> PureHTML.text(html, separator: ", ")
"A, B"

iex> html = PureHTML.parse("<ul>\n  <li>One</li>\n  <li>Two</li>\n</ul>")
iex> PureHTML.text(html, strip: true, separator: ", ")
"One, Two"