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

893 fn:compare: Support for arbitrary atomic types #909

Merged
merged 2 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
172 changes: 158 additions & 14 deletions specifications/xpath-functions-40/src/function-catalog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3624,8 +3624,8 @@ return if (starts-with($preprocessed-value, "-")) then -$abs else +$abs]]></eg>
<fos:function name="compare" prefix="fn">
<fos:signatures>
<fos:proto name="compare" return-type="xs:integer?">
<fos:arg name="value1" type="xs:string?"/>
<fos:arg name="value2" type="xs:string?"/>
<fos:arg name="value1" type="xs:anyAtomicType?"/>
<fos:arg name="value2" type="xs:anyAtomicType?"/>
<fos:arg name="collation" type="xs:string?" default="fn:default-collation()"/>
</fos:proto>
</fos:signatures>
Expand All @@ -3640,22 +3640,133 @@ return if (starts-with($preprocessed-value, "-")) then -$abs else +$abs]]></eg>
<fos:property>focus-independent</fos:property>
</fos:properties>
<fos:summary>
<p>Returns <code>-1</code>, <code>0</code>, or <code>1</code>,
depending on whether <code>$value1</code> collates before,
equal to, or after <code>$value2</code> according to the rules of a selected
collation.</p>
<p>Returns <code>-1</code>, <code>0</code>, or <code>1</code>, depending on whether
the first value is less than, equal to, or greater than the second value.</p>
</fos:summary>
<fos:rules>
<p>Returns <code>-1</code>, <code>0</code>, or <code>1</code>,
depending on whether <code>$value1</code> is
respectively less than, equal to, or greater than <code>$value2</code>,
according to the rules of the collation that is used. </p>
<p>The collation used by this function is determined according to the rules in <specref
ref="choosing-a-collation"/>. </p>
<p>Compares two atomic values <code>$value1</code> and <code>$value2</code> for order, and
returns the integer value <code>-1</code>, <code>0</code>, or <code>1</code>,
depending on whether <code>$value1</code> is less than, equal to, or greater than
<code>$value2</code>, respectively.</p>
<p>If either <code>$value1</code> or <code>$value2</code> is the empty sequence,
the function returns the empty sequence.</p>
<p>This function, <phrase diff="chg" at="2023-01-17">when used with the default collation,</phrase> defines the semantics of the <code>eq</code>, <code>ne</code>,
<code>gt</code>, <code>lt</code>, <code>le</code> and <code>ge</code> operators on <code>xs:string</code> values.</p>
<p>Otherwise, the result is determined as follows:</p>
<olist>
<item>
<p>If <code>$value1</code> is an instance of <code>xs:string</code>,
<code>xs:anyURI</code> or <code>xs:untypedAtomic</code>, and if
<code>$value2</code> is an instance of <code>xs:string</code>, <code>xs:anyURI</code>
or <code>xs:untypedAtomic</code>, the values are compared as strings, and the
result reflects the order according to the rules of the collation that is used.</p>
<p>The collation is determined according to the rules in
<specref ref="choosing-a-collation"/>.</p>
<p><phrase diff="chg" at="2023-01-17">When used with the default collation,</phrase>
the function defines the semantics of the <code>eq</code>, <code>ne</code>,
<code>gt</code>, <code>lt</code>, <code>le</code> and <code>ge</code>
operators on <code>xs:string</code> values.</p>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:numeric</code>, the result of
<code>fn:numeric-compare($value1, $value2)</code> is returned.</p>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:boolean</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:boolean-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:boolean-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>If <code>$value1</code> is an instance of <code>xs:hexBinary</code> or
<code>xs:base64Binary</code>, and if <code>$value2</code> is an instance of
<code>xs:hexBinary</code> or <code>xs:base64Binary</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:binary-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:binary-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:date</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:date-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:date-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:time</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:time-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:time-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:dateTime</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:dateTime-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:dateTime-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:dayTimeDuration</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:dayTimeDuration-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:duration-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>If both <code>$value1</code> and <code>$value2</code> are instances of
<code>xs:yearMonthDuration</code>, then:</p>
<olist>
<item><p><code>-1</code> is returned if
<code>op:yearMonthDuration-less-than($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>0</code> is returned if
<code>op:duration-equal($value1, $value2)</code> returns <code>true</code>.</p>
</item>
<item><p><code>1</code> is returned otherwise.</p></item>
</olist>
</item>
<item>
<p>For any other combination of types, a type error
<xerrorref spec="XP" class="TY" code="0004"/> is raised.</p>
</item>
</olist>
</fos:rules>
<fos:examples>
<fos:example>
Expand Down Expand Up @@ -3698,7 +3809,40 @@ return if (starts-with($preprocessed-value, "-")) then -$abs else +$abs]]></eg>
base characters, such as the final <quote>n</quote>. </fos:postamble>
</fos:test>
</fos:example>
<fos:example>
<fos:test>
<fos:expression>compare(9, 10)</fos:expression>
<fos:result>-1</fos:result>
</fos:test>
</fos:example>
<fos:example>
<fos:test>
<fos:expression>compare(false(), true())</fos:expression>
<fos:result>-1</fos:result>
</fos:test>
</fos:example>
<fos:example>
<fos:test>
<fos:expression>compare(true(), parse-xml-fragment('<x>1</x>'))</fos:expression>
<fos:result>0</fos:result>
</fos:test>
</fos:example>
<fos:example>
<fos:test>
<fos:expression>compare(xs:time('23:59:59'), xs:time('00:00:00'))</fos:expression>
<fos:result>1</fos:result>
</fos:test>
</fos:example>
<fos:example>
<fos:test>
<fos:expression>compare(xs:date('2001-01-01'), xs:untypedAtomic('2001-01-01'))</fos:expression>
<fos:result>0</fos:result>
</fos:test>
</fos:example>
</fos:examples>
<fos:history>
<fos:version version="4.0">Changed in 4.0: Enhanced to accept types other than strings.</fos:version>
</fos:history>
</fos:function>
<fos:function name="codepoint-equal" prefix="fn">
<fos:signatures>
Expand Down
32 changes: 17 additions & 15 deletions specifications/xpath-functions-40/src/xpath-functions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2705,9 +2705,6 @@ string conversion of the number as obtained above, and the appropriate <var>suff
may also cause an error if they cannot be resolved against the <phrase diff="chg" at="2023-05-19">relevant</phrase> base URI.</p></note>

</div3>
<div3 id="func-compare">
<head><?function fn:compare?></head>
</div3>
<div3 id="func-codepoint-equal">
<head><?function fn:codepoint-equal?></head>
</div3>
Expand Down Expand Up @@ -5450,15 +5447,12 @@ correctly in all browsers, depending on the system configuration.</emph></p>-->
<div3 id="func-atomic-equal">
<head><?function fn:atomic-equal?></head>
</div3>
<div3 id="func-starts-with-subsequence" diff="add" at="B">
<head><?function fn:starts-with-subsequence?></head>
</div3>
<div3 id="func-ends-with-subsequence" diff="add" at="B">
<head><?function fn:ends-with-subsequence?></head>
</div3>
<div3 id="func-contains-subsequence" diff="add" at="B">
<head><?function fn:contains-subsequence?></head>
</div3>
<div3 id="func-deep-equal">
<head><?function fn:deep-equal?></head>
</div3>
<div3 id="func-compare">
<head><?function fn:compare?></head>
</div3>
<div3 id="func-distinct-values">
<head><?function fn:distinct-values?></head>
</div3>
Expand All @@ -5468,9 +5462,15 @@ correctly in all browsers, depending on the system configuration.</emph></p>-->
<div3 id="func-index-of">
<head><?function fn:index-of?></head>
</div3>
<div3 id="func-deep-equal">
<head><?function fn:deep-equal?></head>
</div3>
<div3 id="func-starts-with-subsequence" diff="add" at="B">
<head><?function fn:starts-with-subsequence?></head>
</div3>
<div3 id="func-ends-with-subsequence" diff="add" at="B">
<head><?function fn:ends-with-subsequence?></head>
</div3>
<div3 id="func-contains-subsequence" diff="add" at="B">
<head><?function fn:contains-subsequence?></head>
</div3>
</div2>
<div2 id="cardinality-functions">
<head>Functions that test the cardinality of sequences</head>
Expand Down Expand Up @@ -11973,6 +11973,8 @@ declare function eg:distinct-nodes-stable ($arg as node()*) as node()* {
argument syntax in function calls.</p></item>
<item><p>The <code>fn:deep-equal</code> function has an <code>options</code> argument
giving detailed control over how two values are compared.</p></item>
<item><p>The <code>fn:compare</code> function has been enhanced to accept types
other than strings.</p></item>
<item><p>The <code>fn:format-integer</code> function can produce output in non-decimal
radices, for example binary and hexadecimal.</p></item>
<item><p>The <code>fn:json-doc</code> function accepts additional options.</p></item>
Expand Down