Skip to content

Commit

Permalink
332-options-for-fn:path
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelhkay committed Nov 29, 2024
1 parent dd6003c commit 04e4509
Showing 1 changed file with 144 additions and 33 deletions.
177 changes: 144 additions & 33 deletions specifications/xpath-functions-40/src/function-catalog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13381,6 +13381,7 @@ else QName("", $value)</eg>
<fos:signatures>
<fos:proto name="path" return-type="xs:string?">
<fos:arg name="node" type="node()?" default="." usage="navigation"/>
<fos:arg name="options" type="map(*)" default="{}"/>
</fos:proto>
</fos:signatures>
<fos:properties arity="0">
Expand All @@ -13393,64 +13394,130 @@ else QName("", $value)</eg>
<fos:property>context-independent</fos:property>
<fos:property>focus-independent</fos:property>
</fos:properties>
<fos:properties arity="2">
<fos:property>deterministic</fos:property>
<fos:property>context-independent</fos:property>
<fos:property>focus-independent</fos:property>
</fos:properties>
<fos:summary>
<p>Returns a path expression that can be used to select the supplied node relative to the
root of its containing document.</p>
</fos:summary>
<fos:rules>
<p>The behavior of the function if the argument is omitted is exactly the same as if the
<p>The behavior of the function if the <code>$node</code>argument is omitted is exactly the same as if the
context value (<code>.</code>) had been passed as the argument.</p>
<p>If <code>$node</code> is the empty sequence, the function returns the empty sequence.</p>

<p>The <code>$options</code> argument, if present, defines additional parameters controlling
how the output is formatted. The <termref def="option-parameter-conventions"
>option parameter conventions</termref> apply. The options available are as follows:</p>

<fos:options>
<fos:option key="namespaces">
<fos:meaning>A map from namespace prefixes to namespace URIs, such as might be returned
by the function <function>fn:in-scope-namespaces</function>. If a prefix is available
for a given URI, it is used in preference to using <code>Q{uri}local</code> notation.
</fos:meaning>
<fos:type>map((xs:NCName | enum('')), xs:anyURI)?</fos:type>
<fos:default>()</fos:default>
</fos:option>
<fos:option key="indexes">
<fos:meaning>If true, the returned path includes the index positions of nodes. If
false, only the node names are included.
</fos:meaning>
<fos:type>xs:boolean</fos:type>
<fos:default>true</fos:default>
</fos:option>
</fos:options>

<p>If <code>$node</code> is a document node, the function returns the string
<code>"/"</code>.</p>

<p>Otherwise, the function returns a string that consists of a sequence of steps, one
for each ancestor-or-self of <code>$node</code> other than the root node. This string is
prefixed by <code>"Q{http://www.w3.org/2005/xpath-functions}root()"</code> if the root
node is not a document node. Each step consists of the character <code>"/"</code>
for each ancestor-or-self of <code>$node</code> other than the root node.</p>

<p>If the root node is not a document node then this string is preceded by
a string notionally representing a call to the <code>fn:root</code> function,
expressed as follows:</p>

<ulist>
<item><p>If the <code>namespaces</code> option is present and defines a mapping from a
non empty prefix <var>P</var>
to the namespace URI <code>http://www.w3.org/2005/xpath-functions</code>, then
<code>"<var>P</var>:root()"</code></p></item>
<item><p>If the <code>namespaces</code> option is present and defines a mapping from the empty string
to the namespace URI <code>http://www.w3.org/2005/xpath-functions</code>, then
<code>"root()"</code></p></item>
<item><p>Otherwise, <code>"Q{http://www.w3.org/2005/xpath-functions}root()"</code>.</p></item>
</ulist>

<p>Each step consists of the character <code>"/"</code>
followed by a string whose form depends on the kind of node selected by that step, as
follows:</p>

<olist>
<item>
<p>For an element node,
<code>Q{<emph>uri</emph>}<emph>local</emph>[<emph>position</emph>]</code>,
where <code><emph>uri</emph></code> is the namespace URI of the node name or the
empty string if the node is in no namespace, <code><emph>local</emph></code> is
the local part of the node name, and <code><emph>position</emph></code> is an
integer representing the position of the selected node among its like-named
<p>For an element node, then by default
<code>Q{<var>uri</var>}<var>local</var>[<var>position</var>]</code>,
where <var>uri</var> is the namespace URI of the node name or the
empty string if the node is in no namespace, <var>local</var> is
the local part of the node name, and <var>position</var> is an
integer representing the one-based position of the selected node among its like-named
siblings.</p>
<p>The suffix <code>[<var>position</var>]</code> is omitted if the <code>indexes</code>
option is present with the value <code>false</code>.</p>
<p>If the <code>namespaces</code> option is present, and if it includes a mapping
from a namespace prefix to the namespace URI of the element, or to the empty string
if the element is in no namespace, then:</p>
<ulist>
<item><p>If there is more than one such prefix, then one of them is chosen arbitrarily.</p></item>
<item><p>If the namespace prefix is the zero-length string, then the <code>Q{<var>uri</var>}</code> part of the step is
replaced by the empty string.</p></item>
<item><p>If the prefix is an NCName <var>P</var>, then the <code>Q{<var>uri</var>}</code> part of the step is
replaced by <code><var>P</var>:</code>.</p></item>
</ulist>
</item>
<item>
<p>For an attribute node:</p>
<olist>
<item>
<p>if the node is in no namespace, <code>@<emph>local</emph></code>, where
<code><emph>local</emph></code> is the local part of the node name</p>
<p>If the node is in no namespace, <code>@<emph>local</emph></code>, where
<code><emph>local</emph></code> is the local part of the node name.</p>
</item>
<item>
<p>otherwise, <code>@Q{<emph>uri</emph>}<emph>local</emph></code>, where
<p>Otherwise, by default <code>@Q{<emph>uri</emph>}<emph>local</emph></code>, where
<code><emph>uri</emph></code> is the namespace URI of the node name,
and <code><emph>local</emph></code> is the local part of the node name</p>
and <code><emph>local</emph></code> is the local part of the node name.</p>
<p>If the <code>namespaces</code> option is present , and if it includes a mapping
from a non-empty namespace prefix to the namespace URI of the attribute, then
the <code>Q{<var>uri</var>}</code> part of the step is replaced with a namespace
prefix in the same way as for element nodes, described above.</p>
</item>
</olist>
</item>
<item>
<p>For a text node: <code>text()[<emph>position</emph>]</code> where
<code><emph>position</emph></code> is an integer representing the position
of the selected node among its text node siblings</p>
<p>For a text node: <code>text()[<var>position</var>]</code> where
<code><var>position</var></code> is an integer representing the position
of the selected node among its text node siblings.</p>
<p>The suffix <code>[<var>position</var>]</code> is omitted if the <code>indexes</code>
option is present with the value <code>false</code>.</p>
</item>
<item>
<p>For a comment node: <code>comment()[<emph>position</emph>]</code> where
<p>For a comment node: <code>comment()[<var>position</var>]</code> where
<code><emph>position</emph></code> is an integer representing the position
of the selected node among its comment node siblings</p>
of the selected node among its comment node siblings.</p>
<p>The suffix <code>[<var>position</var>]</code> is omitted if the <code>indexes</code>
option is present with the value <code>false</code>.</p>
</item>
<item>
<p>For a processing-instruction node:
<code>processing-instruction(<emph>local</emph>)[<emph>position</emph>]</code>
<code>processing-instruction(<var>local</var>)[<var>position</var>]</code>
where <code><emph>local</emph></code> is the name of the processing instruction
node and <code><emph>position</emph></code> is an integer representing the
position of the selected node among its like-named processing-instruction node
siblings</p>
siblings.</p>
<p>The suffix <code>[<var>position</var>]</code> is omitted if the <code>indexes</code>
option is present with the value <code>false</code>.</p>
</item>
<item>
<p>For a namespace node:</p>
Expand All @@ -13462,14 +13529,16 @@ else QName("", $value)</eg>
namespace node (which represents the namespace prefix).</p>
</item>
<item>
<p>If the namespace node has no name (that is, it represents the default
<p>If the namespace node has no name (that is, if it represents the default
namespace):
<code>namespace::*[Q{http://www.w3.org/2005/xpath-functions}local-name() = ""]</code></p>
<code>namespace::*[<var>U</var>local-name() = ""]</code></p>
<p>Here <code><var>U</var>local-name()</code> represents a call on the function
<code>fn:local-name</code> and is formatted using the same
conventions as the call on <code>fn:root</code> described earlier.</p>
</item>
</olist>
</item>
</olist>

</fos:rules>
<fos:errors>
<p>The following errors may be raised when <code>$node</code> is omitted:</p>
Expand All @@ -13486,6 +13555,16 @@ else QName("", $value)</eg>
</item>
</ulist>
</fos:errors>

<fos:notes>
<p>Using the <code>namespaces</code> option to shorten the generated path is often convenient,
but the resulting path may be unusable if the input tree contains multiple bindings for the same prefix.</p>

<p>A map returned by <code>fn:in-scope-namespaces</code> will never contain an entry that maps any prefix
to the zero-length URI. Such an entry can, however, be added manually, and can be used to control how
no-namespace names are represented in the output (including the option of giving them a non-empty prefix).</p>
</fos:notes>

<fos:examples>
<fos:variable name="e" id="v-path-e"><![CDATA[document {
<p xmlns="http://example.com/one" xml:lang="de" author="Friedrich von Schiller">
Expand All @@ -13497,25 +13576,45 @@ Himmlische, dein Heiligtum.
</fos:variable>
<fos:example>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression>path($e)</fos:expression>
<fos:expression><eg>path($e)</eg></fos:expression>
<fos:result>'/'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression>path($e/*:p)</fos:expression>
<fos:expression><eg>path($e/*:p)</eg></fos:expression>
<fos:result>'/Q{http://example.com/one}p[1]'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression>path($e/*:p/@xml:lang)</fos:expression>
<fos:expression><eg>path($e/*:p, {'namespaces': in-scope-namespaces($e/*)})</eg></fos:expression>
<fos:result>'/p[1]'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression><eg>path($e/*:p, {'indexes': false()})</eg></fos:expression>
<fos:result>'/Q{http://example.com/one}p'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression><eg>path($e/*:p/@xml:lang)</eg></fos:expression>
<fos:result>'/Q{http://example.com/one}p[1]/@Q{http://www.w3.org/XML/1998/namespace}lang'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression>path($e/*:p/@author)</fos:expression>
<fos:expression><eg>path($e//@xml:lang,
{'namespaces': in-scope-namespaces($e/*)})</eg></fos:expression>
<fos:result>'/p[1]/@xml:lang'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression><eg>path($e/*:p/@author)</eg></fos:expression>
<fos:result>'/Q{http://example.com/one}p[1]/@author'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression>path($e/*:p/*:br[2])</fos:expression>
<fos:expression><eg>path($e/*:p/*:br[2])</eg></fos:expression>
<fos:result>'/Q{http://example.com/one}p[1]/Q{http://example.com/one}br[2]'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression><eg>path($e/*:p/*:br[2],
{'namespaces': { 'N': 'http://example.com/one' },
'indexes': false()
})</eg></fos:expression>
<fos:result>'/N:p/N:br'</fos:result>
</fos:test>
<fos:test use="v-path-e" spec="XQuery">
<fos:expression><eg>path(
$e//text()[
Expand All @@ -13534,19 +13633,31 @@ Himmlische, dein Heiligtum.
</fos:variable>
<fos:example>
<fos:test use="v-path-emp" spec="XQuery">
<fos:expression>path($emp)</fos:expression>
<fos:expression><eg>path($emp)</eg></fos:expression>
<fos:result>'Q{http://www.w3.org/2005/xpath-functions}root()'</fos:result>
</fos:test>
<fos:test use="v-path-emp" spec="XQuery">
<fos:expression>path($emp/@xml:id)</fos:expression>
<fos:expression><eg>path($emp/@xml:id)</eg></fos:expression>
<fos:result>'Q{http://www.w3.org/2005/xpath-functions}root()/@Q{http://www.w3.org/XML/1998/namespace}id'</fos:result>
</fos:test>
<fos:test use="v-path-emp" spec="XQuery">
<fos:expression>path($emp/empnr)</fos:expression>
<fos:expression><eg>path($emp/empnr)</eg></fos:expression>
<fos:result>'Q{http://www.w3.org/2005/xpath-functions}root()/Q{}empnr[1]'</fos:result>
</fos:test>
<fos:test use="v-path-emp" spec="XQuery">
<fos:expression><eg>path($emp/empnr,
{ 'namespaces': { 'fn': 'http://www.w3.org/2005/xpath-functions',
'': '' }
})</eg></fos:expression>
<fos:result>'fn:root()/empnr[1]'</fos:result>
</fos:test>
</fos:example>
</fos:examples>
<fos:changes>
<fos:change issue="332" date="2024-11-29">
<p>Options are added to customize the form of the output.</p>
</fos:change>
</fos:changes>
</fos:function>
<fos:function name="root" prefix="fn">
<fos:signatures>
Expand Down Expand Up @@ -16048,7 +16159,7 @@ else error(parse-QName('Q{http://www.w3.org/2005/xqt-errors}FORG0005'))
<fos:rules>

<p>The <code>$options</code> argument, if present, defines additional parameters controlling
how the comparison is done. If it is supplied as a map, then he <termref def="option-parameter-conventions"
how the comparison is done. If it is supplied as a map, then the <termref def="option-parameter-conventions"
>option parameter conventions</termref> apply.</p>
<p>For backwards compatibility reasons, the <code>$options</code> argument can also be set
to a string containing a collation name. Supplying a string <code>$S</code> for this argument is equivalent
Expand Down

0 comments on commit 04e4509

Please sign in to comment.