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.

Selecting nodes in embedded 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.

Selecting nodes in external XML (@href)

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>&#x0A;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;<c>Text</c>&#x0A;&#x20;&#x20;&#x20;</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) is xs: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>&#x0A;&#x20;&#x20;&#x20;<b>&#x0A;&#x20;&#x20;&#x20;&#x20;&#x20;&#x20;<c>Text</c>&#x0A;&#x20;&#x20;&#x20;</b>&#x0A;</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) is xs:anyURI('.../external.xml').

Namespaces in XPath expressions

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.

⚠️ **GitHub.com Fallback** ⚠️