The querySelectorNS and querySelectorAllNS functions are
convenience functions for working with namespaced documents. They
filter out all content that does not belong within the given
namespaces. Note that when searching for particular elements in a
selector, they must have a namespace prefix, e.g. "svg|g".
The filter is relative to doc, so like the un-namespaced
functions these search a node's own subtree rather than the whole
document. A selector starting with :scope replaces the filter
altogether (see below); such a selector is namespaced by its own
prefixes, e.g. ":scope > svg|g".
The namespace argument, ns, is simply passed on to
getNodeSet or xml_find_all if
it is necessary to use a namespace present within the document. This
can be ignored for content lacking a namespace, which is usually the
case when using querySelector or querySelectorAll.
For querySelector and querySelectorAll, leaving
ns as NULL on an xml2 document means the
document's own namespace map is used, which xml_ns
builds by walking the whole document on every query. Passing a
zero-length ns, character(0) or list(), skips
that lookup and queries with no namespaces, which is worth doing on a
large document known to be un-namespaced. It is an error for the
namespaced functions, which have nothing to filter to without a
namespace.
A selector's bare element names match elements in no namespace,
":is(p)" and ":has(p)" exactly as "p" itself
does, so an element in a default namespace has to be reached through
a prefix. With xml2 the document's own prefixes are used when
ns is not given, and xml_ns names a
default namespace d1, making "d1|p" the selector for
those elements.
Queries may be chained: as well as a document or a single node,
doc may be a set of nodes, i.e. an xml2
xml_nodeset or an XML XMLNodeSet, as returned
by querySelectorAll. The selector is then evaluated from each
node of the set in turn, so a relative selector such as ":scope
> a" applies per node. A node that matches from more than one node
of the set is returned only once, at the position it first matched.
An xml2 xml_missing (the result of a failed
xml_find_first) is also accepted, and yields no
matches rather than an error.
Selectors are translated with the generic (XML) translator
unless a translator argument is given to be passed on to
css_to_xpath, with one exception: a
document parsed as HTML by htmlParse or
read_html is queried with the html
translator, so that element and attribute names are matched
case-insensitively and the pseudo-classes that depend on HTML
semantics (:checked, :disabled, :link,
:lang() via the lang attribute, ...) work as they do
in a browser. Passing translator explicitly overrides this
for either kind of document.
The document is recognised however the query starts, so a chain of
queries beginning at an HTML document keeps the html
translator when it continues from one of the document's nodes or
from a set of them.
A selector starting with the :scope pseudo-class is anchored
at the queried node itself: querySelectorAll(node, ":scope >
a") returns only the a children of node, where
querySelectorAll(node, "a") would return all of its a
descendants. :scope after a combinator or within a functional
pseudo-class is an error (it cannot be expressed in XPath 1.0).
When doc is a whole document rather than a node, the queried
node is taken to be the document's root element, so a bare
:scope matches that root element and ":scope > x"
matches its x children. This differs from a browser's
document.querySelectorAll(), where :scope on a
document refers to the document itself: a bare :scope matches
nothing there (the document is not an element), while ":scope
> html" matches the root element. To query starting from the root
element itself rather than the document, pass the root node (e.g.
xmlRoot or xml_root) as
doc instead of the document.