W3C

EXPath Binary Module 4.0

W3C Editor's Draft 4 February 2025

This version:
https://qt4cg.org/specifications/EXPath/binary-40/
Latest version of EXPath Binary Module 4.0:
https://qt4cg.org/specifications/EXPath/binary-40/
Most recent Recommendation of EXPath Binary Module:
http://expath.org/spec/binary
Editors:
Jirka Kosek <http://kosek.com/>
John Lumley <http://www.saxonica.com/>
Michael Kay <http://www.saxonica.com/>

Please check the errata for any errors or issues reported since publication.

See also translations.

This document is also available in these non-normative formats: Specification in XML format and XML function catalog.


Abstract

This document defines an API for XPath 4.0 to handle the manipulation of binary data. It defines extension functions to process data from, and generate data for, binary resources, including extracting subparts, searching, basic binary operations and conversion between binary and structured forms of XDM numbers and strings.

The document is an update of the original [EXPath Binary 1.0] specification, developed by the EXPath Community Group, defined for [XML Path Language (XPath) 2.0] and published in 2013.

The principal semantic alteration is use of functional argument defaults available in XPath 4.0.

These functions are defined for use in [XML Path Language (XPath) 4.0], [XQuery 4.0: An XML Query Language], [XSL Transformations (XSLT) Version 4.0], and other related XML standards.

A summary of changes since published version 1.0 is provided at F Changes since version 1.0.

Status of this Document

This version of the specification is work in progress. It is produced by the QT4 Working Group, officially the W3C XSLT 4.0 Extensions Community Group. Individual functions specified in the document may be at different stages of review, reflected in their Changes notes. Comments are invited, in the form of GitHub issues at https://github.com/qt4cg/qtspecs.

Dedication

The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).


1 Introduction

Changes in 4.0 

  1. Use the arrows to browse significant changes since the 1.0 version of this specification.

  2. Sections with significant changes are marked Δ in the table of contents. New functions introduced in this version are marked ➕ in the table of contents.

The purpose of this document is to define functions to manipulate binary data for inclusion in XPath 4.0, XQuery 4.0, and XSLT 4.0. The binary data is represented by the type xs:base64Binary as defined by Section 3.2.16 base64BinaryXS2.

The syntax used to call these functions and operators is specified in [XML Path Language (XPath) 4.0] and [XQuery 4.0: An XML Query Language].

This document defines several classes of functions:

References to specific sections of some other specifications are indicated by cross-document links in this document. Each such link consists of a pointer to a specific section followed a superscript specifying the linked document. The superscripts have the following meanings: FILE40 [EXPath File 4.0], FO40 [XQuery and XPath Functions and Operators 4.0] and XS2 [XML Schema Part 2: Datatypes Second Edition]

1.1 Error codes

Error conditions are identified by a code (a QName). When such an error condition is reached in the evaluation of an expression, a dynamic error is thrown, with the corresponding error code (as if the standard XPath function error() had been called).

In this specification these codes use the http://expath.org/ns/binary namespace with a local part in the form of a descriptive string, for example bin:index-out-of-range. This convention is used in place of the http://www.w3.org/2005/xqt-errors namespace and alpha-numeric local part, e.g. err:FOCH0004 used in [XQuery and XPath Functions and Operators 4.0]. These error codes have been largely retained from the 1.0 version of the EXPath specification.

Error codes are summarized in B Error summary.

1.2 Binary types

Changes in 4.0  

  1. Binary arguments to the functions are now declared to be either xs:hexBinary or xs:base64Binary, but binary function results remain of type xs:base64Binary. This should not cause any backward incompatibilities as casting back and forth between the two representations has been possible since at least version 2.0

XML Schema, and therefore the XDM data model, defines two primitive atomic types holding binary data: Section 3.2.16 base64BinaryXS2 and Section 3.2.15 hexBinaryXS2. In both cases the value space is a sequence of octets; the two types differ only in how the binary value is converted to or from a string. Although most functions in this specification are not concerned with the string representation of the value, they need to distinguish these two types, and xs:base64Binary has been chosen arbitrarily as the result type for functions that return binary values. Where binary data is supplied as input to a function, however, both xs:base64binary and xs:hexBinary are accepted.

[Definition] The term binary value is used to mean a sequence of octets represented as an instance of xs:base64Binary or xs:hexBinary.

Conversion to and from xs:hexBinary can be performed by casting with xs:hexBinary() and xs:base64Binary().

Note:

Internally it is likely that implementations will use the same byte array representation for both data types, and that casting will merely involve a change in the type annotation; it should not require data to be copied.

[Definition] A ·binary value· that contains no octets is referred to as being zero-length. A zero-length binary value is an item, and as such is a sequence of length one, which is not the same thing as an empty sequence.

1.3 Test suite

A suite of test-cases for all the functions defined in this module, in [QT3] format, is defined at [Test-suite].

1.4 Conformance

This specification follows the general remarks on and terminology for conformance given in Section 1.2 ConformanceFO

In this document, text labeled as an example or as a note is provided for explanatory purposes and is not normative.

1.5 Namespaces and prefixes

The functions defined in this document are contained in the namespace http://expath.org/ns/binary. The conventional prefix for this namespace is bin.

This document uses the prefix bin to refer to this namespace. User-written applications can choose a different prefix to refer to the namespace, so long as it is bound to the correct URI.

1.6 Function signatures and descriptions

Each function (or group of functions having the same name) is defined in this specification using a standard proforma, full details of which can be found in Section 1.5 Function signatures and descriptionsFO. In particular in this version (trailing) optional arguments for functions (introduced in XPath 4.0) are used where appropriate in the signatures, rather than multiple-arity signatures as previously.

All the functions defined in this specification are deterministic and independent of the static and dynamic context.

All the functions described in this specification can in principle be defined in terms of two primitives: bin:to-octets and bin:from-octets, which convert between a ·binary value· and a sequence of xs:unsignedByte values (integers in the range 0 to 255). In many cases functions are specified with reference to a formal equivalent that defines the semantics of the function directly or indirectly in terms of these two primitives.

2 Use cases

Development of this specification was driven by requirements which some XML developers regularly encounter in examining or generating data which is presented in binary, or other non-textual forms. Some typical use cases include:

2.1 Example – finding JPEG size

As an example, the following code reads the binary form of a JPEG image file, searches for the 'Start of Frame/DCT' segment, and unpacks the relevant binary sections to integer-valued attributes height and width:

<xsl:variable name="binary" 
              select="file:read-binary(@href)" 
              as="xs:base64Binary"/>
<xsl:variable name="location" 
              select="bin:find($binary, 0, bin:hex('FFC0'))"/>
<size width="{bin:unpack-unsigned-integer($binary, 
                                          $location+5,
                                          2, 
                                          'most-significant-first')}"
      height="{bin:unpack-unsigned-integer($binary,
                                           $location+7,
                                           2,
                                           'most-significant-first')}"/>

The result is an element such as:

<size width="377" height="327"/>

Note:

The 'most-significant-first' argument could be omitted, because it is the default. This is the numeric format used in JPEG: for further information see 7.1.1 Octet order.

2.2 Example – reading and writing variable length ASN.1 integers

Changes in 4.0  

  1. The functions in this example have been moved into a differing namespace prefix (asn:) to avoid suggesting that they are part of the supported function set.

[ASN.1], used in a number of telecommunications industry standards, defines a binary data syntax (the basic encoding rules) for identifying and encoding arbitrary data as streams of octets. Many of these forms specify the length of data as part of their encoding. For example, an integer has a variable-length representation as a sequence of octets:

  • The first octet has the value 0x02 to indicate that this is an integer.

  • Next, a variable-length length field to indicate the length of the payload. (This is designed to accommodate very large integers, such as those found in cryptography.)

  • Finally, the payload itself: the octets of the integer value in most-significant-first order.

To generate such a representation for an integer from XSLT/XPath, the following code might be used:

 <xsl:function name="asn:int-octets" as="xs:integer*">
    <xsl:param name="value" as="xs:integer"/>
    <xsl:sequence select="if ($value ne 0) 
                          then (bin:int-octets($value idiv 256), $value mod 256) 
                          else ()"/>
 </xsl:function>
 
 <xsl:function name="asn:encode-ASN-integer" as="xs:base64Binary">
    <xsl:param name="int" as="xs:integer"/>
    <xsl:variable name="octets" select="bin:int-octets($int)"/>
    <xsl:variable name="length-octets"
       select="let $l := count($octets) 
               return ( if ($l le 127) 
                        then $l 
                        else ( let $lo := bin:int-octets($l) 
                               return (128+count($lo), $lo)
                             )
                      )"/>
    <xsl:sequence select="bin:from-octets((2,$length-octets,$octets))"/>
 </xsl:function>

The function asn:int-octets returns a sequence of all the significant octets of the integer (i.e. eliminating leading zeroes) in most-significant order. Examples of the encoding are:

 asn:encode-ASN-integer(0) → "AgA="
 asn:encode-ASN-integer(1234) → "AgIE0g=="
 asn:encode-ASN-integer(123456789123456789123456789123456789) → "Ag8XxuPAMviQRa10ZoQEXxU="
               
 asn:encode-ASN-integer(123456789.. 900 digits... 123456789) → "AoIBdgaTo....EBF8V"

The first example requires no octets to encode zero, hence its octets are 2, 0. Both the second and third examples can be represented in less than 128 octets (2 and 15 respectively), so length is encoded as a single octet. The first three octets of the result for the last example, which encodes a 900-digit integer, are: 2, 130, 1 indicating that the data is represented by (130-128) * 256 + 1 = 513 octets and the length required two octets to encode.

Decoding is a matter of compound use of the integer decoding function:

 <xsl:function name="asn:decode-ASN-integer" as="xs:integer">
    <xsl:param name="in" as="xs:base64Binary"/>
    <xsl:sequence
       select="let $lo := bin:unpack-unsigned-integer($in, 1, 1, 'BE') 
               return (
                  if ($lo le 127) 
                  then bin:unpack-unsigned-integer($in, 2, $lo, 'BE') 
                  else ( let $lo2 := $lo - 128, 
                             $lo3 := bin:unpack-unsigned-integer($in, 2 ,$lo2, 'BE') 
                         return bin:unpack-unsigned-integer($in, 2+$lo2, $lo3, 'BE')
                        )
               )"
    />
 </xsl:function>

Note:

All numbers in ASN are 'big-endian'.

This function is the inverse of the encoding function above:

 asn:decode-ASN-integer(xs:base64Binary("AgA=")) → 0
 asn:decode-ASN-integer(xs:base64Binary("AgIE0g==")) → 1234
 asn:decode-ASN-integer(xs:base64Binary("Ag8XxuPAMviQRa10ZoQEXxU=")) 
     → 123456789123456789123456789123456789              
 asn:decode-ASN-integer(xs:base64Binary("AoIBdgaTo....EBF8V")) 
     → 123456789.. 900 digits... 123456789

3 Other Operations on Binary Values

This section provides a summary of operations on binary values beyond those defined in this document.

3.1 Conversions

Casting is defined:

  • Between xs:hexBinary and xs:base64Binary, in either direction. Since the two types have the same value space, conversion is lossless, and can be expected in most implementations to have very low cost.

  • From xs:string to xs:hexBinary or xs:base64Binary. The semantics correspond to the XSD rules for validation of simple types. The two binary types have different lexical representation, so conversion from strings requires different input.

  • From xs:hexBinary or xs:base64Binary to xs:string. The rules are defined in [TITLE OF XP40 SPEC, TITLE OF casting-to-string SECTION]XP40. The two binary types have different lexical representation, so the output in the two cases is different.

3.2 Comparison

Comparison of binary values is defined using any of the value comparison operators eq, ne, le, lt, ge, or gt. It is therefore defined also for the general comparison operators =, !=, <=, <, >=, and >.

The semantics are defined in op:binary-equal and op:binary-less-than.

The two types xs:hexBinary and xs:base64Binary can be compared interchangeably.

Because binary values are ordered, sequences of binary values can be sorted using the function fn:sort, or by using the xsl:sort instruction in XSLT or the order by clause in XQuery.

3.3 Numeric representation

Integers can be converted to a string representation using any radix in the range 2 to 36 using the function fn:format-integer.

Conversely, strings representing an integer using any radix in the range 2 to 36 can be converted to an integer using the function fn:parse-integer.

These functions do not directly involve binary values, but they can be used to convert between numbers and binary values by using a string representation as an intermediate format.

See also the functions bin:pack-integer, bin:unpack-integer, and bin:unpack-unsigned-integer defined in this specification.

3.4 Loading and saving binary data

Changes in 4.0  

  1. The [XQuery and XPath Functions and Operators 4.0] function fn:binary-resource has been added to the list of useful functions.

This module defines no specific functions for reading and writing binary data from external resources, but other specifications provide some suitable mechanisms.

[XQuery and XPath Functions and Operators 4.0] provides a function to retrieve binary resources:

fn:binary-resource(
$filesource as xs:string?
) as xs:base64Binary

The EXPath File Module [EXPath File 4.0] provides three functions suitable for use in file-based situations:

file:read-binary(
$file as xs:string,
$offset as xs:integer? := 0,
$size as xs:integer? := ()
) as xs:base64Binary

which reads binary data from an existing file, with an optional offset and size.

file:write-binary(
$file as xs:string,
$value as xs:base64Binary
) as empty-sequence()

which writes binary data into a new or existing file.

file:append-binary(
$file as xs:string,
$value as xs:base64Binary
) as empty-sequence()

which appends binary data onto the end of an existing file.

4 Defining constants and conversions

The functions in this section can be used to define constant binary values or to perform simple conversions to string representations:

4.1 bin:hex

Changes in 4.0  

  1. The input string is now allowed to include embedded underscores and whitespace.  [Issue 1750 PR 1753 3 February 2025]

Summary

Constructs a binary value from a string of hexadecimal digits ([0-9A-Fa-f]*).

Signature
bin:hex(
$in as xs:string?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If $in is the empty sequence, the function returns an empty sequence.

Any whitespace and underscore characters are stripped from $in.

If the length of of the resulting string is an odd number, then a single "0" digit is prepended to the value, so that it contains an even number of hexadecimal digits.

The resulting string is then cast to type xs:hexBinary, which is then cast to xs:base64Binary.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

$in ! ( replace(., '[_\s]', '') 
           -> concat(if (string-length(.) mod 2) eq 1 then "0" else "", .)
           -> xs:hexBinary(.)
           -> xs:base64Binary(.) )
Error Conditions

[bin:non-numeric-character] is raised if $in cannot be parsed as a hexadecimal number.

Notes

The order of octets in the result follows the order of characters in the string.

If $in is an empty string, the result will be a ·zero-length· xs:base64Binary value.

When the input string has an even number of characters, this function delivers the same result as the expression xs:base64Binary(xs:hexBinary($string)).

Examples
Expression Result
bin:hex('1122_3F4E')
xs:base64Binary("ESI/Tg==")
bin:hex('122 3F4E')
xs:base64Binary("ASI/Tg==")

4.2 bin:bin

Changes in 4.0  

  1. The input string is now allowed to include embedded underscores and whitespace.  [Issue 1750 PR 1753 3 February 2025]

Summary

Constructs a binary value from a string of zeroes and ones ([01]*)

Signature
bin:bin(
$in as xs:string?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If $in is the empty sequence, the function returns an empty sequence.

Any whitespace and underscore characters are stripped from $in.

As many zero digits (U+0030 (DIGIT ZERO, 0) ) as necessary are prepended to $in to make its string length a multiple of 8.

The string is then partitioned into substrings of length 8, and each such substring B is converted to an integer in the range 0 to 255 by applying the function fn:parse-integer(B, 2). The resulting sequence of integers is then converted to a ·binary value· by applying the function bin:from-octets.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

$in ! ( (: process input if present, otherwise return () :)
               (: strip underscores and whitespace :)
           replace(., '[_\s]', '')
               (: extend to a multiple of 8 binary digits :)
       ->  concat((1 to (8 - string-length(.) mod 8) ! "0"), .)
               (: insert a separator after every 8 digits :)
       ->  replace(., "(.{8})", "$1/")
               (: split into groups of 8 digits :)
       ->  tokenize(., "/")
               (: parse each group of 8 binary digits as a radix-2 integer :)
       =!> parse-integer(2)
               (: construct a binary value from these octets :)
       ->  bin:from-octets(.) 
   )
Error Conditions

[bin:non-numeric-character] is raised if $in cannot be parsed as a binary number.

Notes

The order of octets in the result follows the order of characters in the string.

If $in is an empty string, the result will be a ·zero-length· xs:base64Binary value.

Examples
Expression Result
bin:bin('1101_0001_1101_0101')
bin:hex("D1D5")
bin:bin('1 0001 1101 0101')
bin:hex("11D5")
bin:bin(' 101 ')
bin:hex("05")

4.3 bin:octal

Changes in 4.0  

  1. The input string is now allowed to include embedded underscores and whitespace.  [Issue 1750 PR 1753 3 February 2025]

  2. The way in which the value is adjusted to a whole number of octets has been clarified. The rules have been made more precise, and might not match the interpretation adopted by existing implementations.  [Issue 1750 PR 1753 3 February 2025]

Summary

Constructs a binary value from a string of octal digits ([0-7]*)

Signature
bin:octal(
$in as xs:string?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If $in is the empty sequence, the function returns an empty sequence.

Otherwise:

  1. Any whitespace and underscore characters are stripped from $in.

  2. Each octal digit in $in is replaced by its binary equivalent ("0""000", "1""001", "2""010", "3""011", "4""100", "5""101", "6""110", "7""111").

  3. A maximum of two leading zero digits are stripped.

  4. The resulting string is converted to a ·binary value· by applying the function bin:bin to the result.

The order of octets in the result follows the order of characters in the string.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

$in ! ( replace(., '[_\s]', '') 
           =>  characters()
           =!> {"0":"000", "1":"001", "2":"010", "3":"011", 
                "4":"100", "5":"101", "6":"110", "7":"111"}()
           =!> replace("^0?0?", "")     
           =>  string-join()
           =>  bin:bin() )
Error Conditions

[bin:non-numeric-character] is raised if $in cannot be parsed as an octal number.

Notes

The order of octets in the result follows the order of characters in the string.

If $in is a zero-length string, the result will be a ·zero-length· xs:base64Binary value.

The rule for padding to a whole number of octets ensures that leading zeroes are significant in determining the length of the final binary value, while also allowing a value of any length to be constructed. For example (underscores added for readability):

  • An input of "0" translates first to the string "000"; two leading zeros are removed producing "0", which bin:bin converts to bin:hex("00").

  • An input of "155" translates to the binary string "001_101_101". The first two zeroes are removed, and bin:bin converts the result to bin:hex("6D")

  • An input of "355" translates to the binary string "011_101_101". The first zero is removed, and bin:bin converts the result to bin:hex("ED").

  • An input of "555" translates to the string "101_101_101", which bin:bin converts to bin:hex("016D").

  • An input of "0155" translates to the string "000_001_101_101". The first two zeros are stripped giving "0_001_101_101", which bin:bin converts to bin:hex("006D").

Examples
Expression Result
bin:octal('')
bin:hex('')
bin:octal('0')
bin:hex('00')
bin:octal('377')
bin:hex('FF')
bin:octal('777')
bin:hex('01FF')
bin:octal('0377')
bin:hex('00FF')
bin:octal('11_223_047')
bin:hex('252627')

4.4 bin:to-octets

Changes in 4.0  

  1. The result type is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0.

Summary

Returns binary data as a sequence of integer octets.

Signature
bin:to-octets(
$in as (xs:hexBinary | xs:base64Binary)
) as xs:unsignedByte*
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If $in is a ·zero-length· ·binary value· then the empty sequence is returned.

Octets are returned in sequence, as instances of xs:unsignedByte (integers ranging from 0 to 255).

Examples
Expression Result
bin:to-octets(bin:hex('1122AAFF')
17, 34, 170, 255
bin:to-octets(bin:hex(''))
()

4.5 bin:from-octets

Changes in 4.0  

  1. The argument type is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.

Summary

Converts a sequence of octets into binary data.

Signature
bin:from-octets(
$in as xs:unsignedByte*
) as xs:base64Binary
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Octets are integers from 0 to 255.

If $in is the empty sequence, the function returns a ·zero-length· binary value.

Examples
Expression Result
bin:from-octets((17, 34, 170, 255))
bin:hex('1122AAFF')
bin:from-octets(())
bin:hex('')

5 Basic operations

Changes in 4.0  

  1. The function find-all in the example for bin:find has been moved into a differing namespace prefix (f:) to avoid suggesting that it is part of the supported function set.

5.1 bin:length

Summary

Returns the size of a binary value, measured in octets.

Signature
bin:length(
$in as (xs:hexBinary | xs:base64Binary)
) as xs:integer
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Returns the number of octets in the binary value $in.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression.

count(bin:to-octets($in))
Examples
Expression Result
bin:length(bin:hex('FFFF'))
2
bin:length(bin:hex(''))
0

5.2 bin:part

Summary

Selects a specified range of octets from a binary value.

Signature
bin:part(
$in as (xs:hexBinary | xs:base64Binary)?,
$offset as xs:integer,
$size as xs:integer? := ()
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns a section of binary data starting at $offset. The offset is zero-based. If $size is present and non-empty, the size of the returned binary data is $size octets. If $size is absent or empty, all remaining data from $offset is returned.

The $offset is zero based.

The values of $offset and $size must be non-negative integers.

It is a dynamic error if $offset + $size is larger than the size of the binary data in $in.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

$in => bin:to-octets() => subsequence($offset + 1, $size) => bin:from-octets()
Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $in.

[bin:negative-size] is raised if $size is negative.

Notes

The function differs in several ways from fn:subsequence() and fn:substring():

  • The $offset and $size are supplied as integers, not doubles.

  • The $offset is zero-based, not one-based.

  • An error is raised if the selection goes outside the bounds of the value.

Examples
Expression:

bin:part(bin:hex('11223344556677'), 0, 4)

Result:
bin:hex('11223344')
Expression:

bin:part(bin:hex('11223344556677'), 4)

Result:
bin:hex('556677')
Expression:

bin:part(bin:hex('11223344556677'), 7)

Result:
bin:hex('')
Expression:

bin:part(bin:hex('11223344556677'), 5, 0)

Result:
bin:hex('')

This example tests whether $data starts with binary content consistent with a PDF file:

bin:part($data, 0, 4) eq bin:hex("25504446")

25504446 is the magic number for PDF files: it is the hexadecimal representation of the result of encoding the string "%PDF" in UTF-8 (or US-ASCII). Note that the function bin:encode-string can be used to convert a string to its binary representation.

5.3 bin:join

Summary

Concatenates a sequence of binary values in order.

Signature
bin:join(
$in as (xs:hexBinary | xs:base64Binary)*
) as xs:base64Binary
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

The function returns an xs:base64Binary value created by concatenating the binary values in the sequence $in, in order.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression.

$in =!> bin:to-octets() => bin:from-octets()
Notes

If $in is the empty sequence, the function returns a ·zero-length· binary value.

Examples
Expression Result
bin:join((bin:hex('0000'), bin:hex('FFFF'), bin:hex('0000'))
bin:hex('0000FFFF0000')
bin:join(())
bin:hex('')
bin:join( (1 to 4) ! bin:hex('F0') )
bin:hex('F0F0F0F0')

5.4 bin:insert-before

Summary

Inserts octets at a given point in a binary value.

Signature
bin:insert-before(
$in as (xs:hexBinary | xs:base64Binary)?,
$offset as xs:integer,
$extra as (xs:hexBinary | xs:base64Binary)?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

If the value of $extra is the empty sequence, the function returns $in.

Otherwise, the function returns a binary value formed by concatenating the bin:part($in, 0, $offset), then $extra, then bin:part($in, $offset) $extra, and then the remaining data from $in.

The $offset is zero based, and must be non-negative.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

$in => bin:to-octets() 
    => insert-before($offset + 1, bin:to-octets($extra)) 
    => bin:from-octets()
Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset is larger than the size of the binary data of $in.

Notes

If $offset is zero, the result is the binary concatenation of $extra and $in.

Examples
Expression Result
bin:insert-before(bin:hex('FFFF'), 1, bin:hex('00'))
bin:hex('FF00FF')
bin:insert-before(bin:hex('FFFF'), 0, bin:hex('00'))
bin:hex('00FFFF')
bin:insert-before(bin:hex('FFFF'), 2, bin:hex('00'))
bin:hex('FFFF00')

5.5 bin:pad-left

Changes in 4.0  

  1. The argument type for $octet is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.  [Issue 1750 PR 1753 3 February 2025]

Summary

Returns a binary value created by padding $in on the left with $count occurrences of $octet.

Signature
bin:pad-left(
$in as (xs:hexBinary | xs:base64Binary)?,
$count as xs:integer,
$octet as xs:unsigned-byte? := 0
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns a binary value consisting of $count instances of $octet, followed by $in. The default for $octet is zero (0).

$size must be a non-negative integer.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

(((1 to $count) ! $octet), bin:to-octets($in)) 
=> bin:from-octets()
Error Conditions

[bin:negative-size] is raised if $size is negative.

Examples
Expression Result
bin:pad-left(bin:hex('FFFF'), 3)
bin:hex('000000FFFF')
bin:pad-left(bin:hex('0000'), 3, 255)
bin:hex('FFFFFF0000')
bin:pad-left(bin:hex(''), 8)
bin:hex('0000000000000000')

5.6 bin:pad-right

Changes in 4.0  

  1. The argument type for $octet is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.  [Issue 1750 PR 1753 3 February 2025]

Summary

Returns a binary value created by padding $in on the right with $count occurrences of $octet.

Signature
bin:pad-right(
$in as (xs:hexBinary | xs:base64Binary)?,
$count as xs:integer,
$octet as xs:unsignedByte? := 0
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns a binary value consisting of $in, followed by $count instances of $octet. The default for $octet is zero (0).

$size must be a non-negative integer.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

(bin:to-octets($in), (1 to $count) ! $octet) 
=> bin:from-octets()
Error Conditions

[bin:negative-size] is raised if $size is negative.

Examples
Expression Result
bin:pad-right(bin:hex('FFFF'), 3)
bin:hex('FFFF000000')
bin:pad-right(bin:hex('0000'), 3, 255)
bin:hex('0000FFFFFF')
bin:pad-right(bin:hex(''), 8)
bin:hex('0000000000000000')

5.7 bin:find

Summary

Returns the position of the first occurrence of $search within $in, starting at $offset.

Signature
bin:find(
$in as (xs:hexBinary | xs:base64Binary)?,
$offset as xs:integer,
$search as (xs:hexBinary | xs:base64Binary)
) as xs:integer?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

Otherwise, the function returns the lowest value of P that is greater than or equal to $offset, such that bin:part($in, P, bin:length($search)) eq P. If there is no such value (that is, if $search is not found), the function returns the empty sequence.

If $search is ·zero-length· then $offset is returned.

The value of $offset must be a non-negative integer.

The $offset is zero based.

The returned location is zero based.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

($offset to (bin:length($in) - bin:length($search)))
       [bin:part($in, 0, bin:length($search)) eq $search][1]
Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset is larger than the size of the binary data of $in.

Notes

Finding all the matches can be accomplished with simple recursive application:

<xsl:function name="f:find-all" as="xs:integer*">
     <xsl:param name="data" as="xs:base64Binary?"/>
     <xsl:param name="offset" as="xs:integer"/>
     <xsl:param name="pattern" as="xs:base64Binary"/>
     <xsl:sequence
         select="if (bin:length($pattern) eq 0) 
                 then ()
                 else let $found := bin:find($data,$offset,$pattern) 
                      return if ($found) 
                             then ($found,
                                   if ($found + 1 lt bin:length($data)) 
                                   then f:find-all($data, $found + 1, $pattern) 
                                   else ())
                             else ()"/>
</xsl:function>
Examples
Expression Result
bin:find((bin:hex('AABBCCDD'), 0, bin:hex('DD'))
3
bin:find((bin:hex('AABBCCDD'), 0, bin:hex('FF'))
()
bin:find((bin:hex('AABBCCDDBBCC'), 2, bin:hex('BBCC'))
4
bin:find((bin:hex('AABBCCDD'), 2, bin:hex(''))
2

6 Text decoding and encoding

6.1 bin:decode-string

Summary

Decodes a binary value as a string in a given encoding.

Signature
bin:decode-string(
$in as (xs:hexBinary | xs:base64Binary)?,
$encoding as xs:string? := 'utf-8',
$offset as xs:integer? := 0,
$size as xs:integer? := ()
) as xs:string?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

If $offset and $size are provided, the $size octets from $offset are decoded. If $offset alone is provided, octets from $offset to the end are decoded, otherwise the entire octet sequence is decoded.

The function returns the string obtained by decoding the selected octets using the specified $encoding name.

The $encoding argument is the name of an encoding. The values for $encoding follow the same rules as for the encoding attribute in an XML declaration. The only values which every implementation is required to recognize are utf-8 and utf-16.

If $encoding is omitted, utf-8 encoding is assumed.

The values of $offset and $size, if present, must be non-negative integers.

$offset is zero based.

Error Conditions

[bin:index-out-of-range]is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $in.

[bin:negative-size] is raised if $size is negative.

[bin:unknown-encoding] is raised if $encoding is invalid or not supported by the implementation.

[bin:conversion-error] is raised if there is an error or malformed input during decoding the string. Additional information about the error may be passed through suitable error reporting mechanisms – this is implementation-dependant.

Examples
Expression:

bin:decode-string(bin:hex('414243'))

Result:
"ABC"
Expression:

bin:decode-string(bin:hex('FEFF004100420043'), 'utf-16')

Result:
"ABC"

(TODO: See issue 1751 regarding the BOM.)

The following tests whether the binary value $data starts with four octets that decode to the string '%PDF' (which always appears at the start of a PDF file)

bin:decode-string($data, 'UTF-8', 0, 4) eq '%PDF'

6.2 bin:encode-string

Summary

Encodes a string into a binary value using a given encoding.

Signature
bin:encode-string(
$in as xs:string?,
$encoding as xs:string? := 'utf-8'
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

The $encoding argument is the name of an encoding. The values for $encoding follow the same rules as for the encoding attribute in an XML declaration. The only values which every implementation is required to recognize are utf-8 and utf-16.

The function returns the binary value obtained by encoding the string $in using the specified $encoding name.

If $encoding is omitted, utf-8 encoding is assumed.

Error Conditions

[bin:unknown-encoding] is raised if $encoding is invalid or not supported by the implementation.

[bin:conversion-error]is raised if there is an error or malformed input during encoding the string. Additional information about the error may be passed through suitable error reporting mechanisms – this is implementation-dependant.

Examples
Expression Result
bin:encode-string('ABC')
bin:hex('414243')
bin:encode-string('ABC', 'utf-16')
bin:hex('FEFF004100420043')

(TODO: The result has a BOM. See issue 1751.)

7 Packing and unpacking of encoded numeric values

7.1 Numeric representation

7.1.1 Octet order

Changes in 4.0 

  1. The octet-order parameter of relevant functions now has an enum type rather than a string type. In consequence, supplying an incorrect value is now a type error ([bin:TY0004]XP) and no longer has a custom error code.   [Issue 1750 ]

Packing and unpacking numeric values within binary data can be performed in 'most-significant-first' ('big-endian') or 'least-significant-first' ('little-endian') octet order. The default is 'most-significant-first'. The relevant functions have an optional parameter $octet-order whose string value controls the order. Least-significant-first order is indicated by any of the values least-significant-first, little-endian or LE. Most-significant-first order is indicated by any of the values most-significant-first, big-endian or BE.

The type of the octet-order argument to the relevant function is given as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE').

By default, functions that convert numeric values to binary use most-significant-first ordering. This corresponds to the order most commonly used in network protocols, and is often referred to as network order. If least-significant-first ordering is requested, the order of octets in the result is reversed. This ordering, although often used internally within computer hardware, is less commonly encountered in network protocol standards: two places where it is used are the DICOM standard for medical imaging, and the Bitcoin standard for cryptocurrency.

7.1.2 Integer representation

Integers within binary data are represented, or assumed to be represented, as an integral number of octets. Integers where $length is greater than 8 octets (and thus not representable as a long) might be expected in some situations, e.g. encryption. Whether the range of integers is limited to ±2^63 is implementation-dependentFO.

7.1.3 Representation of floating point numbers

When packing and unpacking floating point numbers (xs:float and xs:double), the binary representations are expected to correspond with those of the IEEE single/double-precision 32/64-bit floating point types [IEEE 754-1985]. Consequently they will occupy 4 or 8 octets when packed.

Special float and double formats are represented in IEEE format as follows:

  • INF maps to 0x7f80_0000 (float), or 0x7ff0_0000_0000_0000 (double).

  • -INF maps to 0xff80_0000 (float), or 0xfff0_0000_0000_0000 (double).

  • Negative zero maps to 0x8000_0000 (float), or 0x8000_0000_0000_0000 (double).

  • NaN in the XSD and XDM type system corresponds to a quiet NaN as defined in [IEEE 754-1985], and therefore maps to 0x7fc0_0000 (float), or 0x7ff8_0000_0000_0000 (double). These are the bit forms that will be packed.

  • IEEE signalling NaN values may be encountered in binary data, with the value range 0x7f80_0001 to 0x7fbf_ffff (float), or 0x7ff0_0000_0000_0001 to 0x7ff7_ffff_ffff_ffff or 0xfff0_0000_0000_0001 to 0xfff7_ffff_ffff_ffff (double). Any such value encountered during unpacking will be replaced by a quiet NaN. Any low-order payload in an unpacked quiet NaN is also zeroed.

7.2 bin:pack-double

Summary

Returns the 8-octet binary representation of an xs:double value.

Signature
bin:pack-double(
$in as xs:double,
$octet-order as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:base64Binary
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Most-significant-octet-first number representation is assumed unless the $octet-order parameter specifies otherwise. Acceptable values for $octet-order are described in 7.1.1 Octet order.

The binary representation will correspond with that of the IEEE double-precision 64-bit floating point type [IEEE 754-1985]. For more details see 7.1.3 Representation of floating point numbers.

7.3 bin:pack-float

Summary

Returns the 4-octet binary representation of a float value.

Signature
bin:pack-float(
$in as xs:float,
$octet-order as xs:enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:base64Binary
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Most-significant-octet-first number representation is assumed unless the $octet-order parameter is specified. Acceptable values for $octet-order are described in 7.1.1 Octet order.

The binary representation will correspond with that of the IEEE single-precision 32-bit floating point type [IEEE 754-1985]. For more details see 7.1.3 Representation of floating point numbers.

7.4 bin:pack-integer

Summary

Returns the twos-complement binary representation of an integer value as a binary value of a given size.

Signature
bin:pack-integer(
$in as xs:integer,
$size as xs:integer,
$octet-order as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:base64Binary
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

The function produces a binary value containing the twos-complement representation of $in mod math:pow(256, $size), padded on the left to $size octets with zero bits if the value is positive, or one bits if it is negative.

The order of octets in the result is most-significant-first unless $octet-order specifies otherwise. Acceptable values for $octet-order are described in 7.1.1 Octet order. If least-significant-first ordering is requested then the order of octets in the result is reversed.

Specifying a $size of zero yields a ·zero-length· binary value.

Error Conditions

[bin:negative-size] is raised if $size is negative.

Notes

If the integer being packed has a maximum precision of $size octets, then signed/unsigned versions are not necessary. If the data is considered unsigned, then the most significant bit of the bottom $size octets has a normal positive (2^(8 *$size - 1)) meaning. If it is considered to be a signed value, then the MSB and all the higher order, discarded bits will be '1' for a negative value and '0' for a positive or zero. If this function were to check the sizing of the supplied integer against the packing size, then any values of MSB and the discarded higher order bits other than 'all 1' or 'all 0' would constitute an error. This function does not perform such checking.

Least-significant-first byte ordering simply reverses the octets in the result.

Examples
Expression Result
bin:pack-integer(256, 2)
bin:hex('0100')
bin:pack-integer(256, 4)
bin:hex('00000100')
bin:pack-integer(65536, 2)
bin:hex('0000')
bin:pack-integer(256, 2, "LE")
bin:hex('0001')
bin:pack-integer(-1, 2)
bin:hex('FFFF')
bin:pack-integer(-2, 4)
bin:hex('FFFFFFFE')
bin:pack-integer(-2, 4, 'LE')
bin:hex('FEFFFFFF')

7.5 bin:unpack-double

Summary

Extracts an xs:double value held in IEEE format at the given offset in a binary value.

Signature
bin:unpack-double(
$in as (xs:hexBinary | xs:base64Binary),
$offset as xs:integer,
$octet-order as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:double
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Extract the double value stored in the 8 successive octets from the $offset octet of the binary data of $in.

Most-significant-first number representation is assumed unless the $octet-order parameter specifies otherwise. Acceptable values for $octet-order are described in 7.1.1 Octet order.

The value of $offset must be a non-negative integer.

The $offset is zero based.

The binary representation is expected to correspond with that of the IEEE double-precision 64-bit floating point type [IEEE 754-1985]. For more details see 7.1.3 Representation of floating point numbers.

Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset + 8 (octet-length of xs:double) is larger than the size of the binary data of $in.

7.6 bin:unpack-float

Summary

Extract float value stored at the particular offset in binary data.

Signature
bin:unpack-float(
$in as (xs:hexBinary | xs:base64Binary),
$offset as xs:integer,
$octet-order as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:float
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Extract the float value stored in the 4 successive octets from the $offset octet of the binary data of $in.

Most-significant-octet-first number representation is assumed unless the $octet-order parameter specifies otherwise. Acceptable values for $octet-order are described in 7.1.1 Octet order.

The value of $offset must be a non-negative integer.

The $offset is zero based.

The binary representation is expected to correspond with that of the IEEE single-precision 32-bit floating point type [IEEE 754-1985]. For more details see 7.1.3 Representation of floating point numbers.

Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset + 4 (octet-length of xs:float) is larger than the size of the binary data of $in.

7.7 bin:unpack-integer

Summary

Returns a signed integer value represented by the $size octets starting from $offset in the input binary value.

Signature
bin:unpack-integer(
$in as (xs:hexBinary | xs:base64Binary),
$offset as xs:integer,
$size as xs:integer,
$octet-order as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:integer
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

The function produces an integer represented by the binary value bin:part($in, $offset, $size). This is interpreted as a twos-complement representation of a signed integer, with the most significant octet first unless the $octet-order option specifies otherwise.

Acceptable values for $octet-order are described in 7.1.1 Octet order. If least-significant-first ordering is requested then the order of octets in the input is reversed.

The values of $offset and $size must be non-negative integers.

$offset is zero based.

Specifying a $size of zero yields the integer 0.

Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $in.

[bin:negative-size] is raised if $size is negative.

Notes

For discussion on integer range see 7.1.2 Integer representation.

Examples
Expression Result
bin:unpack-integer(bin:hex('0100'), 0, 2)
256
bin:unpack-integer(bin:hex('00000100'), 0, 4)
256
bin:unpack-integer(bin:hex('FFFF'), 0, 2)
-1
bin:unpack-integer(bin:hex('00FFFFFFFF'), 1, 4)
-1
bin:unpack-integer(bin:hex('FEFF'), 0, 2, "LE")
-2

7.8 bin:unpack-unsigned-integer

Summary

Returns an unsigned integer value represented by the $size octets starting from $offset in the input binary representation.

Signature
bin:unpack-unsigned-integer(
$in as (xs:hexBinary | xs:base64Binary),
$offset as xs:integer,
$size as xs:integer,
$octet-order as enum('least-significant-first', 'little-endian', 'LE', 'most-significant-first', 'big-endian', 'BE')? := 'most-significant-first'
) as xs:integer
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

The function produces an integer represented by the binary value bin:part($in, $offset, $size). This is interpreted as a representation of an unsigned integer, with the most significant octet first unless the $octet-order option specifies otherwise.

Acceptable values for $octet-order are described in 7.1.1 Octet order. If least-significant-first ordering is requested then the order of octets in the input is reversed.

The values of $offset and $size must be non-negative integers.

$offset is zero based.

Specifying a $size of zero yields the integer 0.

Error Conditions

[bin:index-out-of-range] is raised if $offset is negative or $offset + $size is larger than the size of the binary data of $in.

[bin:negative-size] is raised if $size is negative.

Notes

For discussion on integer range see 7.1.2 Integer representation.

Examples
Expression Result
bin:unpack-unsigned-integer(bin:hex('0100'), 0, 2)
256
bin:unpack-unsigned-integer(bin:hex('00000100'), 0, 4)
256
bin:unpack-unsigned-integer(bin:hex('FFFF'), 0, 2)
65535
bin:unpack-unsigned-integer(bin:hex('00FFFFFFFF'), 1, 4)
4294967295
bin:unpack-integer(bin:hex('FEFF'), 0, 2, "LE")
65279

8 Bitwise operations

8.1 bin:or

Summary

Returns the bitwise OR of two binary values.

Signature
bin:or(
$a as (xs:hexBinary | xs:base64Binary)?,
$b as (xs:hexBinary | xs:base64Binary)?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If either argument is the empty sequence, an empty sequence is returned.

Otherwise, $a and $b must have the same length.

The function converts $a and $b to sequences of bits A and B, and returns a binary value in which the Nth bit is set to 1 if either or both of the Nth bit of A and the Nth bit of B are 1, and is set to 0 otherwise.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

let $toBin := fn($x) { bin:to-octets($x) 
                        =!> format-integer('2^xxxxxxxx') 
                        => string-join() } 
let $A := $toBin($a) => characters(),
    $B := $toBin($b) => characters()
       
let $R := for-each-pair($A, $B, fn($p, $q) { if ($p eq '1' or $q eq '1')
                                             then '1' else '0 } )
return bin:bin($R)
Error Conditions

[bin:differing-length-arguments] is raised if the input arguments are of differing length.

8.2 bin:xor

Summary

Returns the bitwise exclusive-OR of two binary arguments.

Signature
bin:xor(
$a as (xs:hexBinary | xs:base64Binary)?,
$b as (xs:hexBinary | xs:base64Binary)?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If either argument is the empty sequence, an empty sequence is returned.

Otherwise, $a and $b must have the same length.

The function converts $a and $b to sequences of bits A and B, and returns a binary value in which the Nth bit is set to 1 if the Nth bit of A differs from the Nth bit of B, and is set to 0 if they are the same.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

let $toBin := fn($x) { bin:to-octets($x) 
                        =!> format-integer('2^xxxxxxxx') 
                        => string-join() } 
let $A := $toBin($a) => characters(),
    $B := $toBin($b) => characters()
       
let $R := for-each-pair($A, $B, fn($p, $q) { if ($p ne $q)
                                             then '1' else '0' } )
return bin:bin($R)
Error Conditions

[bin:differing-length-arguments] is raised if the input arguments are of differing length.

8.3 bin:and

Summary

Returns the bitwise AND of two binary arguments.

Signature
bin:and(
$a as (xs:hexBinary | xs:base64Binary)?,
$b as (xs:hexBinary | xs:base64Binary)?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If either argument is the empty sequence, an empty sequence is returned.

Otherwise, $a and $b must have the same length.

The function converts $a and $b to sequences of bits A and B, and returns a binary value in which the Nth bit is set to 1 if both the Nth bit of A and the Nth bit of B are 1, and is set to 0 otherwise.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

let $toBin := fn($x) { bin:to-octets($x) 
                        =!> format-integer('2^xxxxxxxx') 
                        => string-join() } 
let $A := $toBin($a) => characters(),
    $B := $toBin($b) => characters()
       
let $R := for-each-pair($A, $B, fn($p, $q) { if ($p eq '1' and $q eq '1')
                                             then '1' else '0 } )
return bin:bin($R)
Error Conditions

[bin:differing-length-arguments] is raised if the input arguments are of differing length.

8.4 bin:not

Summary

Returns the "bitwise not" of a binary argument.

Signature
bin:not(
$in as (xs:hexBinary | xs:base64Binary)?
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

Returns "bitwise not" applied to $in.

If the argument is the empty sequence, an empty sequence is returned.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

let $toBin := fn($x) { bin:to-octets($x) 
                           =!> format-integer('2^xxxxxxxx') 
                           => string-join() } 
   return $toBin($in) 
          => translate('01', '10') 
          => bin:bin()

8.5 bin:shift

Summary

Shift the bits of a binary value left or right.

Signature
bin:shift(
$in as (xs:hexBinary | xs:base64Binary)?,
$by as xs:integer
) as xs:base64Binary?
Properties

This function is deterministicFO, context-independentFO, and focus-independentFO.

Rules

If the value of $in is the empty sequence, the function returns an empty sequence.

In other cases the length of the result is always the same as the length of $in.

If $by is positive then bits are shifted $by times to the left. The first $by bits are discarded, and $by zero bits are injected at the end.

If $by is negative then bits are shifted -$by times to the right. The last -$by bits are discarded, and -$by zero bits are injected at the start.

If $by is zero, the result is identical to $in.

If abs($by) is greater than the bit-length of $in then an all-zeros result, of the same length as $in, is returned.

abs($by) can be greater than 8, implying multi-byte shifts.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression, except in error cases.

(: convert to a string of 1s and 0s :)
   let $s := bin:to-octets($in) 
             =!> format-integer('2^xxxxxxxx') 
             => string-join()
   
   (: the length of the input in bits :)          
   let $len := string-length($s)
   
   (: a string of zeros equal in length to the size of the shift :)
   let $padding := string-join((1 to abs($by)) ! '0')
   
   (: the binary value as a string, padded left and right :)
   let $padded-string := $padding || $s || $padding
   
   (: the relevant substring of the padded string :)
   let $shifted := substring($padded-string, $len - $by, $len)
   
   (: the result of converting back to a binary value :)
   return bin:bin($shifted)
Notes

Bit shifting across byte boundaries implies 'big-endian' treatment, i.e. the leftmost (high-order) bit when shifted left becomes the low-order bit of the preceding byte.

Examples
Expression:
bin:shift(bin:hex("000001"), 17)
Result:
bin:hex("020000")

A References

A.1 Normative references

EXPath Binary 1.0
Binary Module 1.0. Jirka Kosek and John Lumley, editors. EXPath Module. 3 December 2013.
EXPath File 4.0
EXPath File Module 4.0, Christian Grün, Matthias Brantner and Gabriel Petrovay, editors. XSLT Extensions Community Group, World Wide Web Consortium.
IEEE 754-1985
IEEE 754-2019
IEEE. IEEE Standard for Floating-Point Arithmetic.
XML Path Language (XPath) 2.0
XML Path Language (XPath) 2.0 (Second Edition), Don Chamberlin, Anders Berglund, Scott Boag, et. al., Editors. World Wide Web Consortium, 14 December 2010. This version is https://www.w3.org/TR/2010/REC-xpath20-20101214/. The latest version is available at https://www.w3.org/TR/xpath20/.
XQuery and XPath Functions and Operators 4.0
XQuery and XPath Functions and Operators 4.0, XSLT Extensions Community Group, World Wide Web Consortium.
XML Path Language (XPath) 4.0
XSL Transformations (XSLT) Version 4.0
CITATION: T.B.D.
XQuery and XPath Data Model (XDM) 4.0
XQuery and XPath Data Model (XDM) 4.0, XSLT Extensions Community Group, World Wide Web Consortium.
XQuery 4.0: An XML Query Language
CITATION: T.B.D.
XML Schema Part 2: Datatypes Second Edition
XML Schema Part 2: Datatypes Second Edition, Oct. 28 2004. Available at: http://www.w3.org/TR/xmlschema-2/

A.2 Non-normative references

ASN.1
OSI networking and system aspects – Abstract Syntax Notation One (ASN.1) – see ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER) . ITU-T X.690 (07/2002)
Test-suite
The test suite for this module, using QT3 format, is in the EXPath repository http://github.com/expath/expath-cg in the directory tests/qt3/binary/
QT3
XML Query Test Suite. W3C 21 June 2013.
EXPath
EXPath: Collaboratively Defining Open Standards for Portable XPath Extensions. http://expath.org/.

B Error summary

The error text provided with these errors is non-normative.

bin:conversion-error

Error in converting to/from a string.

bin:differing-length-arguments, Arguments of different length

The two arguments to a bitwise operation are of differing lengths.

bin:index-out-of-range

Attempting to retrieve data outside the meaningful range of a binary data type.

bin:negative-size

Size of binary portion, required numeric size or padding is negative.

bin:non-numeric-character

Wrong character in binary 'numeric constructor' string.

bin:octet-out-of-range

Attempting to pack binary value with octet outside range 0-255.

err:FOoctet-out-of-range
(Error code unused?)
bin:unknown-encoding

The specified encoding is not supported.

bin:unknown-significance-order

Unknown octet-order value.

err:FOunknown-significance-order
(Error code unused?)

C Glossary (Non-Normative)

binary value

The term binary value is used to mean a sequence of octets represented as an instance of xs:base64Binary or xs:hexBinary.

zero-length

A ·binary value· that contains no octets is referred to as being zero-length. A zero-length binary value is an item, and as such is a sequence of length one, which is not the same thing as an empty sequence.

D Other Functions (Non-Normative)

This Appendix describes some sources of functions or operators that fall outside the scope of the function library defined in this specification. It includes both function specifications and function implementations. Inclusion of a function in this appendix does not constitute any kind of recommendation or endorsement; neither is omission from this appendix to be construed negatively. This Appendix does not attempt to give any information about licensing arrangements for these function specifications or implementations.

D.1 XPath Functions and Operators Defined in Other W3C Recommendations

A number of W3C Recommendations make use of XPath, and in some cases such Recommmendations define additional functions to be made available when XPath is used in a specific host language.

D.1.1 Functions and Operators Defined in XPath and XQuery Functions and Operators

Of particular interest to this specification, [XQuery and XPath Functions and Operators 4.0] defines

  • Comparison operators on xs:hexBinary and xs:base64Binary values, defining the semantics of the eq, ne, lt and ge operators applied to binary data. Each returns a boolean value.

  • A function to retrieve the value of a binary resource

Function name Availability Notes
Section 11.1.1 op:binary-equalFO XPath4.0+ Returns true if both binary values contain the same octet sequence.
Section 11.1.2 op:binary-less-thanFO XPath4.0+ Returns true if the first argument is less than the second.
[TITLE OF FO40 SPEC, TITLE OF func-binary-resource SECTION]FO40 XPath4.0+ Returns a resource as xs:base64Binary.

D.2 Functions Defined by Community Groups

D.2.1 Functions Defined in EXPath File

Of particular interest to this specification, [EXPath File 4.0] defines the following functions for input and output of xs:base64Binary values:

Function name Availability Notes
Section 4.5 file:read-binaryFILE XPath4.0+ Returns the content of a file in its Base64 representation.
Section 4.9 file:write-binaryFILE XPath4.0+ Writes a Base64 item as binary data to a file.
Section 4.2 file:append-binaryFILE XPath4.0+ Appends a Base64 item as binary data to a file.

E Checklist of implementation-defined features (Non-Normative)

    F Changes since version 1.0 (Non-Normative)

    F.1 Summary of Changes

    1. Use the arrows to browse significant changes since the 1.0 version of this specification.

      See 1 Introduction

    2. Sections with significant changes are marked Δ in the table of contents. New functions introduced in this version are marked ➕ in the table of contents.

      See 1 Introduction

    3. Binary arguments to the functions are now declared to be either xs:hexBinary or xs:base64Binary, but binary function results remain of type xs:base64Binary. This should not cause any backward incompatibilities as casting back and forth between the two representations has been possible since at least version 2.0

      See 1.2 Binary types

    4. The functions in this example have been moved into a differing namespace prefix (asn:) to avoid suggesting that they are part of the supported function set.

      See 2.2 Example – reading and writing variable length ASN.1 integers

    5. The [XQuery and XPath Functions and Operators 4.0] function fn:binary-resource has been added to the list of useful functions.

      See 3.4 Loading and saving binary data

    6. The result type is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0.

      See 4.4 bin:to-octets

    7. The argument type is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.

      See 4.5 bin:from-octets

    8. The function find-all in the example for bin:find has been moved into a differing namespace prefix (f:) to avoid suggesting that it is part of the supported function set.

      See 5 Basic operations

    9. The octet-order parameter of relevant functions now has an enum type rather than a string type. In consequence, supplying an incorrect value is now a type error ([bin:TY0004]XP) and no longer has a custom error code.

      See 7.1.1 Octet order

    10. PR 1753 

      The input string is now allowed to include embedded underscores and whitespace.

      See 4.1 bin:hex

      See 4.2 bin:bin

      See 4.3 bin:octal

      The way in which the value is adjusted to a whole number of octets has been clarified. The rules have been made more precise, and might not match the interpretation adopted by existing implementations.

      See 4.3 bin:octal

      The argument type for $octet is changed from xs:integer to xs:unsignedByte. This is made possible by the more liberal coercion rules defined in XPath 4.0. A consequence of the change is that supplying an out-of-range integer value is now a type error with the standard error code XPTY0004, rather than the custom error code bin:octet-out-of-range previously used.

      See 5.5 bin:pad-left

      See 5.6 bin:pad-right

    F.2 Changes to Function Signatures

    1. The function signatures of all the specified signatures now use the 'optional argument' syntax of XPath 4.0 where appropriate, rather than giving several signatures of differing arity. Other than that, no intended change to the semantics of the functions are assumed.

    F.3 Editorial Changes

    These changes are not highlighted in the change-marked version of the specification.

    1. The example functions in 2.2 Example – reading and writing variable length ASN.1 integers have been moved into a differing namespace prefix (asn:) to avoid suggesting that they are part of the supported function set. This is in accordance with the principle that the namespace http://expath.org/ns/binary is reserved solely for use in QNames for functions specified in this module.

    G Compatibility with Previous Versions (Non-Normative)

    This section summarizes the extent to which this specification is compatible with previous versions.

    Version 4.0 of this function library is fully backwards compatible with version 1.0, except as noted below:

    1. The use of optional arguments in the function signatures means that minor alterations to possible function calls, which would be invalid in 1.0, are now supported. For example:

      bin:decode-string($string,'utf-8',0,())

      would be invalid in 1.0, as the fourth argument $size is defined to be of type xs:integer. It is valid for 4.0 as the empty sequence denotes default behaviour, that is decoding all octets after $offset

      The functions bin:decode-string,bin:encode-string, bin:pack-double, bin:pack-float, bin:pack-integer, bin:pad-left, bin:pad-right, bin:part, bin:unpack-double, bin:unpack-float, bin:unpack-integer and bin:unpack-unsigned-integer all have similar incompatibilities.

    2. The use of the type xs:unsignedByte for octet arguments, and of an enum type for octet order, means that invalid values for these arguments will now result in a type error [bin:TY0004]XP, rather than a dynamic error with a code in the bin namespace.

    3. The way in which bin:octal adjusts the supplied value to a whole number of octets is now specified much more precisely, and the result might differ from the interpretation adopted by existing implementations. Specifically, the result might differ through the presence or absence of leading zero octets.