Selecting Nodes - xspec/xspec GitHub Wiki
You can use @select
on x:context
, x:expect
, x:param
and x:variable
elements to select specific nodes in embedded XML or external XML.
If you specify @select
with embedded XML, it is evaluated in a document node of embedded XML:
<x:param name="p" select="a/b">
<a>
<b>
<c>Text</c>
</b>
</a>
</x:param>
-
$p
is<b><c>Text</c></b>
. (Whitespace-only text nodes are discarded.) -
$p instance of element(b)
is true. -
root($p) instance of document-node(element(a))
is true. -
root($p)/a/b is $p
is true. -
base-uri($p)
is undefined. -
a/b
matches elements not in any namespace because XSpec defaults to the null namespace for XPath expressions.
Specifying no @select
implies select="child::node()"
:
<x:param name="p">
<a>
<b>
<c>Text</c>
</b>
</a>
</x:param>
-
$p
is<a><b><c>Text</c></b></a>
. (Whitespace-only text nodes are discarded.) -
$p instance of element(a)
is true. -
root($p) instance of document-node(element(a))
is true. -
root($p)/child::node() is $p
is true. -
base-uri($p)
is undefined.
If you want to specify the document node, specify so in @select
:
<x:param name="p" select="/">
<a>
<b>
<c>Text</c>
</b>
</a>
</x:param>
-
$p
is a document node containing<a><b><c>Text</c></b></a>
. (Whitespace-only text nodes are discarded.) -
$p instance of document-node(element(a))
is true. -
root($p) is $p
is true. -
base-uri($p)
is undefined.
Specifying select="self::document-node()"
leads to the same result.
If you specify @select
with external XML (@href
), it is evaluated in a document node of external XML:
external.xml
<?xml version="1.0" encoding="UTF-8"?>
<a>
<b>
<c>Text</c>
</b>
</a>
XSpec
<x:param name="p" select="a/b" href="external.xml" />
-
$p
is<b>
      <c>Text</c>
   </b>
. (Whitespace-only text nodes are intact.) -
$p instance of element(b)
is true. -
root($p) instance of document-node(element(a))
is true. -
root($p)/a/b is $p
is true. -
base-uri($p)
isxs:anyURI('.../external.xml')
. -
a/b
matches elements not in any namespace because XSpec defaults to the null namespace for XPath expressions.
If you specify no @select
, the document node is selected:
<x:param name="p" href="external.xml" />
-
$p
is a document node containing<a>
   <b>
      <c>Text</c>
   </b>
</a>
. (Whitespace-only text nodes are intact.) -
$p instance of document-node(element(a))
is true. -
root($p) is $p
is true. -
base-uri($p)
isxs:anyURI('.../external.xml')
.
Whether you use embedded XML or external XML, XPath expressions in @select
default to the null namespace. If you want to specify XML elements in a namespace, @select
must indicate the namespace using a prefix or Q{...}
notation.
In the next example, the declaration xmlns:db="http://docbook.org/ns/docbook"
binds a namespace to the db
prefix and uses the prefix in @select
. In tests for XQuery, the namespace declaration must be on <x:description>
. Otherwise, the declaration can be on the XSpec element with the @select
attribute or an ancestor of that element.
<x:description xmlns:db="http://docbook.org/ns/docbook" ...other attributes...>
...
<x:param name="p" select="db:section/db:para">
<section xmlns="http://docbook.org/ns/docbook">
<para>
<phrase>Text</phrase>
</para>
</section>
</x:param>
...
</x:description>
or, equivalently,
<x:description xmlns:db="http://docbook.org/ns/docbook" ...other attributes...>
...
<x:param name="p" select="db:section/db:para">
<db:section>
<db:para>
<db:phrase>Text</db:phrase>
</db:para>
</db:section>
</x:param>
...
</x:description>
-
$p
is<para><phrase>Text</phrase></para>
where both elements are in the "http://docbook.org/ns/docbook" namespace. (Whitespace-only text nodes are discarded.) -
$p instance of element(db:para)
is true. -
$p instance of element(Q{http://docbook.org/ns/docbook}para)
is also true, using different notation. -
root($p) instance of document-node(element(db:section))
is true. -
root($p)/db:section/db:para is $p
is true. -
base-uri($p)
is undefined.
XSpec does not have a feature analogous to xpath-default-namespace
in XSLT, so XPath expressions in XSpec @select
or @test
attributes must specify the namespace unless they mean the null namespace.
For a set of concrete files that illustrate namespace usage in XSpec, see namespace-demo_query.xspec and namespace-demo_stylesheet.xspec.