A library for querying HTML using CSS selectors, like JavaScripts document.querySelector/document.querySelectorAll.
Nimquery is available on Nimble:
nimble install nimquery
from xmltree import `$`
from htmlparser import parseHtml
import nimquery
let html = """
<!DOCTYPE html>
<html>
<head><title>Example</title></head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</body>
</html>
"""
let xml = parseHtml(html)
let elements = xml.querySelectorAll("p:nth-child(odd)")
echo elements
# => @[<p>1</p>, <p>3</p>]proc querySelectorAll*(root: XmlNode,
queryString: string,
options: set[QueryOption] = DefaultQueryOptions): seq[XmlNode]Get all elements matching queryString.
Raises ParseError if parsing of queryString fails.
See Options for information about the options parameter.
proc querySelector*(root: XmlNode,
queryString: string,
options: set[QueryOption] = DefaultQueryOptions): XmlNodeGet the first element matching queryString, or nil if no such element exists.
Raises ParseError if parsing of queryString fails.
See Options for information about the options parameter.
proc parseHtmlQuery*(queryString: string,
options: set[QueryOption] = DefaultQueryOptions): QueryParses a query for later use.
Raises ParseError if parsing of queryString fails.
See Options for information about the options parameter.
proc exec*(query: Query,
root: XmlNode,
single: bool): seq[XmlNode]Execute an already parsed query. If single = true, it will never return more than one element.
The QueryOption enum contains flags for configuring the behavior when parsing/searching:
optUniqueIds: Indicates if id attributes should be assumed to be unique.optSimpleNot: Indicates if only simple selectors are allowed as an argument to the:not(...)psuedo-class. Note that combinators are not allowed in the argument even if this flag is excluded.optUnicodeIdentifiers: Indicates if unicode characters are allowed inside identifiers. Doesn't affect strings where unicode is always allowed.
The default options is defined as const DefaultQueryOptions* = { optUniqueIds, optUnicodeIdentifiers, optSimpleNot }.
Below is an example of using the options parameter to allow a complex :not(...) selector.
import xmltree
import htmlparser
import streams
import nimquery
let html = """
<!DOCTYPE html>
<html>
<head><title>Example</title></head>
<body>
<p>1</p>
<p class="maybe-skip">2</p>
<p class="maybe-skip">3</p>
<p>4</p>
</body>
</html>
"""
let xml = parseHtml(newStringStream(html))
let options = DefaultQueryOptions - { optSimpleNot }
let elements = xml.querySelectorAll("p:not(.maybe-skip:nth-child(even))", options)
echo elements
# => @[<p>1</p>, <p class="maybe-skip">3</p>, <p>4</p>]Nimquery supports all CSS3 selectors except the following: :root, :link, :visited, :active, :hover, :focus, :target, :lang(...), :enabled, :disabled, :checked, ::first-line, ::first-letter, ::before, ::after. These selectors will not be implemented because they don't make much sense in the situations where Nimquery is useful.