Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1602 Editorial update to "other operations" on maps and arrays #1603

Merged
merged 2 commits into from
Nov 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 53 additions & 45 deletions specifications/xpath-functions-40/src/xpath-functions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8883,6 +8883,8 @@ return <table>

<div2 id="map-operations">
<head>Other Operations on Maps </head>

<p><emph>This section is non-normative.</emph></p>

<p>Because a map is a function item, functions that apply to functions also apply
to maps. A map is an anonymous function, so <code>fn:function-name</code> returns the empty
Expand All @@ -8893,6 +8895,25 @@ return <table>
<p>There is no function or operator to atomize a map or convert it to a string (other than <code>fn:serialize</code>,
which can be used to serialize some maps as JSON texts).</p>

<p>XPath 4.0 defines a number of syntactic constructs that operate on maps. These all have equivalents
in the function library:</p>

<ulist>
<item><p>The expression <code>{}</code> creates an empty map. This is equivalent to the
effect of the data model primitive <code>dm:empty-map()</code>. Using user-visible functions
the same can be achieved by calling <code>map:build(())</code>, <code>map:of-pairs(())</code>,
or <code>map:merge(())</code>.</p></item>
<item><p>The map constructor <code>{ <var>K1</var> : <var>V1</var>, <var>K2</var> : <var>V2</var>,
... , <var>K/n</var> : <var>V/n</var> }</code> is equivalent to
<code>map:merge((map:entry(<var>K1</var>, <var>V1</var>), map:entry(<var>K1</var>, <var>V1</var>), ..., map:entry(<var>K/n</var>, <var>V/n</var>)), {"duplicates":"reject"})</code></p></item>
<item><p>The lookup expression <code>$map?*</code> is equivalent to <code>map:values($map)</code>.</p></item>
<item><p>The lookup expression <code>$map?K</code>, where <var>K</var> is a key value, is equivalent to
<code>map:get($map, <var>K</var>)</code></p></item>
<item><p>The expression <code>for key $k value $v in $map return <var>EXPR</var></code> is equivalent to the function
call <code>map:for-each($map, fn($k, $v) { <var>EXPR</var> })</code>.</p></item>

</ulist>

</div2>
</div1>
<div1 id="arrays">
Expand Down Expand Up @@ -9064,55 +9085,42 @@ return <table>
</div3>
</div2>
<div2 id="additional-array-operations" diff="add" at="2023-02-20">
<head>Additional Operations on Arrays</head>
<head>Other Operations on Arrays</head>
<p><emph>This section is non-normative.</emph></p>

<p>Arrays may be compared using the <code>fn:deep-equal</code> function.</p>

<p>The XPath language provides explicit syntax for certain operations on arrays.
These constructs can also be specified in terms of function primitives:</p>
These constructs can all be specified in terms of function primitives:</p>

<div3 id="singleton-arrays">
<head>Singleton Arrays</head>
<ulist>
<item><p><code>array { $sequence }</code> constructs an array whose members
are the items in <code>$sequence</code>. Every member of this array will
be a singleton item. This can be defined as
<code>array:join($sequence ! array { . })</code>.</p></item>
<item><p><code>[E1, E2, E3, ..., En]</code> constructs an array in which
<code>E1</code> is the first member, <code>E2</code> is the second member,
and so on. The result is equivalent to the expression
<code>array:join(([ E1 ], [ E2 ], ... [ En ])). </code></p></item>
<item><p>The lookup expression <code>$array?*</code> is equivalent to
<code>array:split($array)?*</code>.</p></item>
<item><p>The lookup expression <code>$array?$N</code>, where <code>$N</code>
is an integer within the bounds of the array, is equivalent to
<code>array:split($array)[$N]?*</code>.</p></item>
<item><p>Similarly, applying the array as a function, <code>$array($N)</code>,
is also equivalent to
<code>array:split($array)[$N]?*</code></p></item>
</ulist>
</div3>

<div3 id="value-maps">
<head>Value Maps</head>
<ulist>
<item><p><code>array { $sequence }</code> constructs an array whose members
are the items in <code>$sequence</code>. Every member of this array will
be a singleton item. This can be defined as
<code>array:of-members($sequence ! { 'value': . })</code>.</p></item>
<item><p><code>[E1, E2, E3, ..., En]</code> constructs an array in which
<code>E1</code> is the first member, <code>E2</code> is the second member,
and so on. The result is equivalent to the expression
<code>array:of-members(({ 'value': E1 }, { 'value': E2 },
{ 'value': E3 }, ... { 'value': En })). </code></p></item>
<item><p>The lookup expression <code>$array?*</code> is equivalent to
<code>array:members($array) ! ?value</code>.</p></item>
<item><p>The lookup expression <code>$array?$N</code>, where <code>$N</code>
is an integer within the bounds of the array, is equivalent to
<code>array:members($array)[$N]?value</code>.</p></item>
<item><p>Similarly, applying the array as a function, <code>$array($N)</code>,
is also equivalent to
<code>array:members($array)[$N]?value</code></p></item>
</ulist>
</div3>
<ulist>
<item><p>An empty array can be constructed using either of the expressions
<code>[]</code> or <code>array{}</code>. The effect is the same as the data model primitive
<code>dm:empty-array(())</code>. Using user-visible functions it can be achieved
by calling <code>array:build(())</code> or <code>array:of-members(())</code>.</p></item>
<item><p>The expression <code>array { $sequence }</code> constructs an array whose members
are the items in <code>$sequence</code>. Every member of this array will
be a singleton item. The effect is the same as
<code>array:build($sequence)</code>.</p></item>
<item><p>The expression <code>[<var>E1</var>, <var>E2</var>, <var>E3</var>, ..., <var>E/n</var>]</code> constructs an array in which
<code>E1</code> is the first member, <code>E2</code> is the second member,
and so on. The result is equivalent to the expression
<code>[] => array:append(<var>E1</var>) => array:append(<var>E2</var>) => ... => array:append(<var>E/n</var>))). </code></p></item>
<item><p>The lookup expression <code>$array?*</code> returns the
<xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref>
of the members of the array. It is equivalent to calling
<code>array:fold-left($array, (), fn($result, $next){ $result, $next })</code>.</p></item>
<item><p>The lookup expression <code>$array?$N</code>, where <code>$N</code>
is an integer within the bounds of the array, is equivalent to
<code>array:get($array, $N)</code>.</p></item>
<item><p>Similarly, applying the array as a function, <code>$array($N)</code>,
is also equivalent to <code>array:get($array, [$N])</code></p></item>
<item><p>The expression <code>for member $m in $array return <var>EXPR</var></code>
is equivalent to <code>array:for-each($array, fn($m){ <var>EXPR</var> })</code>.</p></item>
</ulist>


</div2>

</div1>
Expand Down