This document is also available in these non-normative formats: Specification in XML format and XML function catalog.
Copyright © 2000 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This document defines constructor functions, operators, and functions on the datatypes defined in [XML Schema Part 2: Datatypes Second Edition] and the datatypes defined in [XQuery and XPath Data Model (XDM) 4.0]. It also defines functions and operators on nodes and node sequences as defined in the [XQuery and XPath Data Model (XDM) 4.0]. These functions and operators are defined for use in [XML Path Language (XPath) 4.0] and [XQuery 4.0: An XML Query Language] and [XSL Transformations (XSLT) Version 4.0] and other related XML standards. The signatures and summaries of functions defined in this document are available at: http://www.w3.org/2005/xpath-functions/.
A summary of changes since version 3.1 is provided at H Changes since 3.1.
This section describes the status of this document at the time of its publication. Other documents may supersede this document.
This document is a working draft developed and maintained by a W3C Community Group, the XQuery and XSLT Extensions Community Group unofficially known as QT4CG (where "QT" denotes Query and Transformation). This draft is work in progress and should not be considered either stable or complete. Standard W3C copyright and patent conditions apply.
The community group welcomes comments on the specification. Comments are best submitted as issues on the group's GitHub repository.
As the Community Group moves towards publishing dated, stable drafts, some features that the group thinks may likely be removed or substantially changed are marked “at risk” in their changes section. In this draft:
The community group maintains two extensive test suites, one oriented to XQuery and XPath, the other to XSLT. These can be found at qt4tests and xslt40-test respectively. New tests, or suggestions for correcting existing tests, are welcome. The test suites include extensive metadata describing the conditions for applicability of each test case as well as the expected results. They do not include any test drivers for executing the tests: each implementation is expected to provide its own test driver.
The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).
Maps were introduced as a new datatype in XDM 3.1. This section describes functions that operate on maps.
A map is a kind of item.
[Definition] A map consists of a sequence of entries, also known as key-value pairs. Each entry comprises a key which is an arbitrary atomic item, and an arbitrary sequence called the associated value.
[Definition] Within a map, no two entries have the same key. Two atomic items K1 and K2 are the same key for this purpose if the function call fn:atomic-equal($K1, $K2) returns true.
It is not necessary that all the keys in a map should be of the same type (for example, they can include a mixture of integers and strings).
Maps are immutable, and have no identity separate from their content. For example, the map:remove function returns a map that differs from the supplied map by the omission (typically) of one entry, but the supplied map is not changed by the operation. Two calls on map:remove with the same arguments return maps that are indistinguishable from each other; there is no way of asking whether these are “the same map”.
A map can also be viewed as a function from keys to associated values. To achieve this, a map is also a function item. The function corresponding to the map has the signature function($key as xs:anyAtomicValue) as item()*. Calling the function has the same effect as calling the map:get function: the expression $map($key) returns the same result as get($map, $key). For example, if $books-by-isbn is a map whose keys are ISBNs and whose assocated values are book elements, then the expression $books-by-isbn("0470192747") returns the book element with the given ISBN. The fact that a map is a function item allows it to be passed as an argument to higher-order functions that expect a function item as one of their arguments.
The fn:element-to-map function converts a tree rooted at an XML element node to a corresponding tree of maps, in a form suitable for serialization as JSON. In effect it provides a mechanism for converting XML to JSON.
This section describes the mappings used by this function.
This mapping is designed with three objectives:
It should be possible to represent any XML element as a map suitable for JSON serialization.
The resulting JSON should be intuitive and easy to use.
The JSON should be consistent and stable: small variations in the input should not result in large variations in the output.
Achieving all three objectives requires design compromises. It also requires sacrificing some other desiderata. In consequence:
The conversion is not lossless (see 14.5.914.5.8 Lost XDM Information for details).
The conversion is not streamable.
The results are not necessarily compatible with those produced by other popular libraries.
The requirement for consistency and stability is particularly challenging. An element such as <name>John</name> maps naturally to the map { "name": "John" }; but adding an attribute (so it becomes <name role="first">John</name>) then requires an incompatible change in the JSON representation. The format could be made extensible by converting <name>John</name> to { "name": {"#content":"John"} } and <name role="first">John</name> to { "name": { "@role":"first", "#content":"John" } }, but this imposes unwanted complexity on the simplest cases. The solution adopted is threefold:
It is possible to analyze a corpus of XML documents to develop a conversion plan, which can then be applied consistently to individual input documents, whether or not these documents were present in the corpus. The conversion plan can be serialized and subsequently reused, so that it can be applied to input documents that might not have existed at the time the conversion plan was formulated.
Alternatively, the function can make use of schema information where available, so it considers not just the structure of an individual element instance, but the rules governing the element type.
It is possible to override the choices made by the system, and explicitly specify the format to be used for elements or attributes having a given name.
The key challenge in mapping XML to JSON is in deciding how element content is to be represented. To illustrate the variety of mappings that are possible, the following table lists some examples of typical XML elements and their JSON equivalents:
| XML element | JSON equivalent |
|---|---|
<hr/> | "hr": "" |
<date-of-birth>2023-05-18</date-of-birth> | "date-of-birth": "2023-05-18" |
<box width="5" height="10"/> | "box": { "@width": "5", "@height": "10" } |
<label id="t41">Warning!</label> | "label": { "@id": "t41", "#content": "Warning!" } |
<box>
<width>5</width>
<height>10</height>
</box> | "box": {
"width": 5,
"height": 10
} |
<polygon>
<point x="0" y="0"/>
<point x="1" y="0"/>
<point x="1" y="1"/>
<point x="0" y="1"/>
</polygon> | "polygon": [
{ "x": 0, "y": 0 },
{ "x": 1, "y": 0 },
{ "x": 1, "y": 1 },
{ "x": 0, "y": 1 }
] |
This specification defines a number of named mappings, called layouts, and allows the layout for a particular element to be selected in a number of different ways:
The layout to be used for a specific elements can be explicitly selected by supplying a conversion plan as input to the fn:element-to-map function.
It is possible to construct a conversion plan by analyzing a corpus of documents using the fn:element-to-map-plan function.
It is also possible to construct a conversion plan manually, or to modify the conversion plan produced by the fn:element-to-map-plan function before use.
In the absence of an explicit conversion plan, if the data has been schema-validated, the layout is inferred from the content model for the element type as defined in the schema.
When the data is untyped and no specific layout has been selected, a default layout is chosen based on the properties of the individual element instance.
The advantage of using schema information is that it gives a consistent representation for all elements of a particular type, even if they vary in content: for example if an element type allows optional attributes, the JSON representation will be consistent between those elements that have attributes and those without. In the absence of a schema, consistency can be achieved by supplying a conversion plan that applies uniformly to multiple documents.
The different layouts available are defined in the following sections. For each layout there is a table showing:
Layout name: the name to be used to select this layout in a conversion plan supplied to the fn:element-to-map function.
Usage: the situations for which this layout is designed.
Example input: an example of a typical element for which this layout is appropriate, shown as serialized XML.
Example output: the result of converting this example, shown as serialized JSON. The result is always shown as a singleton map, which is how it will appear when the layout is used for the top-level elements supplied in the $elements argument; when used to convert a descendant element, the corresponding key-value pair may appear as part of a larger map, depending on the layout chosen for its parent element..
Note:
The fn:element-to-map function produces a map as its result, but it is convenient to illustrate the form of the map by showing the effect of serializing the map as JSON.
Mapping rules: The rules for mapping the XML element to an XDM map representation.
Mapping for nilled elements: special rules that apply to an element having the attribute xsi:nil="true". These rules only apply if the element has been schema-validated.
Errors: situations where the layout cannot be used, and where attempting to use it will fail. For example, the empty layout cannot be used for an element that is not empty. In such a situation the recovery action is as follows, in order:
Attributes are dropped, and if this is sufficient to enable the layout to be used, then the element is converted without its attributes.
If the type of an element or attribute in the conversion plan is given as boolean or numeric, but the actual value of the element or attribute is not castable to xs:boolean or xs:numeric respectively, then the node is output ignoring the type property, that is, as an instance of xs:untypedAtomic.
If the conversion plan supplies a fallback layout (an entry with key "*"), then the fallback layout is used.
The element-to-map function fails with a dynamic error.
The rules for selecting the layout for a particular element are given later, in 14.5.614.5.5 Selecting an element layout.
Note that it is possible to request any layout for any element. If an inappropriate layout is chosen for a particular element (for example, empty layout for an element that is not empty), then the rules for that layout specify what happens. It is possible to specify a fallback layout for use when the selected layout fails: this will typically be a layout such as xml or mixed that can handle any element.
Note:
Acknowledgements for this categorization: see [Goessner]. Although Goessner's categories have been used, the detailed mappings vary from his proposal.
| Layout name |
|
|---|---|
| Usage | Intended for XML elements that have no content but may have attributes. |
| Example input | <hr class="ccc" id="zzz"/> |
| Example output | { "hr": { "@class": "ccc", "@id": "zzz" } } |
| Mapping rules | The content is represented by a map containing one entry for each attribute in the XML element; if there are no attributes, the content is represented as the empty map. The rules for attribute names are defined in 14.5.714.5.6 Element and Attribute Names, and the rules for attribute content in 14.5.814.5.7 Element and Attribute Content. |
| Mapping for nilled elements | An additional key-value pair |
| Errors | Child comment nodes, processing instructions, and whitespace-only text nodes are discarded. If any other child nodes are present, this layout fails. |
| Layout name |
|
|---|---|
| Usage | Intended for XML elements that have simple content and no attributes. |
| Example input | <date>2023-05-30</date> |
| Example output | { "date": "2023-05-30" } |
| Mapping rules | The element is atomized and the resulting atomized value is handled as described in 14.5.814.5.7 Element and Attribute Content. If atomization fails, the element is treated as if it were untyped. Note: If the element is untyped, the atomized value will always appear in the result as an instance of |
| Mapping for nilled elements | The content is represented by the value |
| Errors | Attributes are discarded, along with child comment nodes and processing instructions; whitespace is retained. If any child elements are present, this layout fails. |
| Layout name |
|
|---|---|
| Usage | Intended for XML elements that have simple content and (optionally) attributes. |
| Example input | <price currency="USD">23.50</date> |
| Example output | { "price": { "@currency": "USD", "#content": 23.50 } } |
| Mapping rules | The element is represented by a map containing one entry for each of its attributes, plus an entry with key The rules for attribute names are defined in 14.5.714.5.6 Element and Attribute Names, and the rules for attribute content in 14.5.814.5.7 Element and Attribute Content. Note: If the element is untyped, the value of each attribute, and of If the element has been schema-validated, the types of the items in the atomized value are retained. |
| Mapping for nilled elements | The |
| Errors | Child comment nodes and processing instructions are discarded; whitespace is retained. If any child elements are present, this layout fails. |
| Layout name |
|
|---|---|
| Usage | Intended for XML elements that contain mixed content (that is, elements that contain both child elements and child text nodes, intermingled). The element may or may not have attributes. |
| Example input | <para id="x">This is a <i>fine</i> mess!</para> |
| Example output | { "para": [
{ "@id": "x" },
"This is a ",
{ "i": "fine" },
"mess!"
] } |
| Mapping rules | The content is represented by an XDM array containing one entry for each attribute in the XML element, and one entry for each child node, in order. Each attribute node is represented within this array by a single-entry map: the rules for attribute names are defined in 14.5.714.5.6 Element and Attribute Names, and the rules for attribute content in 14.5.814.5.7 Element and Attribute Content. Child nodes are represented within the array as follows:
Whitespace text nodes are retained. |
| Mapping for nilled elements | A nilled element is indicated by including an additional map |
| Errors | All children are retained, including comments, processing instructions, and text nodes, whether or not they are whitespace-only. This layout never fails. |
It is possible to create a conversion plan by analyzing a collection of sample input documents. The function fn:element-to-map-plan is supplied with a collection of nodes (which will normally be element or document nodes), and it examines all the elements within the trees rooted at these nodes, looking for commonalities among like-named elements.
The output of this function (the conversion plan) holds information about how elements and attributes (identified by name) should be converted.
For elements, the information is primarily a mapping from element names (xs:QName instances) to layout names. In some cases additional information beyond the layout name is also included. The conversion plan is represented as an XDM map, whose structure is defined in this specification. A conversion plan can be constructed directly, or the plan produced by calling fn:element-to-map-plan can be modified before use. The plan can be serialized using the JSON output method and reloaded so that the same plan is used whenever a query or stylesheet is executed.
The fn:element-to-map-plan function selects a layout for a given element name N by applying the following rules:
Let $EE be the set of all elements named N, specifically $input/descendant-or-self::*[node-name(.) eq N].
If empty($EE/(* | text()) (that is, if there are no child elements or text nodes) then:
If empty($EE/@*) (that is, if there are no attributes), then the layout is empty: see 14.5.1.1 Layout: Empty Content.
Otherwise, the layout is empty-plus: see 14.5.1.2 Layout: Empty Content with Attributes.
If empty($EE/*) (that is, if there are no child elements) then:
If empty($EE/@*) (that is, if there are no attributes) then the layout is simple: see 14.5.1.3 Layout: Simple Content.
Otherwise, simple-plus: see 14.5.1.4 Layout: Simple Content with Attributes.
The plan also includes the property type. If all the elements in $EE are castable as xs:boolean, then the type is boolean; otherwise, if all the elements in $EE as castable as xs:numeric, then the type is numeric; otherwise, the type is string.
If empty($EE/text()[normalize-space()]) (that is, there are no text node children other than whitespace), then:
If all-equal($EE/*/node-name()) and exists($EE/*[2]) (that is, if all child elements have the same name, and at least one element has multiple child elements), then:
If empty($EE/@*) (that is, if there are no attributes) then list: see 14.5.1.5 Layout: Simple List.
Otherwise, list-plus: see 14.5.1.6 Layout: List with Attributes.
If every $e in $EE satisfies all-different($e/*/node-name()) (that is, the child elements are uniquely named among their siblings), then record: see 14.5.1.7 Layout: Record.
Otherwise, sequence: see 14.5.1.8 Layout: Sequence.
Otherwise, mixed: see 14.5.1.9 Layout: Mixed.
For elements with simple content (more specifically, elements where the chosen layout is simple or simple-plus) the conversion plan also includes an entry indicating whether the content should be represented as a boolean, a number, or a string. If every instance of the element name has content that is castable to xs:boolean, the plan indicates "type": "boolean". If every instance of the element name has content that is castable to xs:numeric, the plan indicates "type": "numeric". In other cases, the plan indicates "type": "string"; however, this may be omitted because it is the default.
For attributes, the conversion plan identifies whether attributes (with a given name) should be represented as booleans, numbers, or strings; alternatively, it may indicate that attributes with a given name should be discarded. For every distinct attribute name present in the input, an entry is output associating the attribute name with one of the types boolean or numeric; the entry is generally omitted when the values are to be represented as strings, though the type can also be given explicitly as string. An entry with type boolean is generated for an attribute name if all the attributes with that name are castable as xs:boolean. Similarly, an entry with type numeric is generated for an attribute name if all the attributes with that name are castable as xs:numeric. In other case, the attributes are treated as being of type string. Entries with type string may be omitted, since that is the default. The entry for an attribute may also specify "type": "skip" to indicate that the attribute should be discarded.
A plan that is produced by analyzing a corpus of input documents can then be customized by the user if required. For example:
If simple layout is chosen for a particular element name, but it is known that some documents might be encountered in which that element has attributes, then simple might be changed to simple-plus.
If record layout is chosen for a particular element name, but it is known that some documents might be encountered in which child elements can be repeated, then record might be changed to sequence.
If a generated plan determines that phone numbers should be represented as numbers, it might be modified to treat them as strings.
The conversion plan is a map of type map(xs:string, record(*)). The key is an element or attribute name, representing element names in the form Q{uri}local, and attributes in the form @Q{uri}localnotation: in both cases the Q{uri} part must be omitted for a name in no namespace. Strings are used as keys in preference to xs:QName instances to allow the plan to be serialized in JSON format.
A more detailed definition of the structure is given in 14.5.414.5.3 Structure of the conversion plan.
A small example might be (in its JSON serialization):
{ "bookList": { "layout": "list", "child": "book" },
"book": { "layout": "record" },
"author": { "layout": "simple" },
"title": { "layout": "simple" },
"price": { "layout": "simple", "type": "numeric" },
"hardback": { "layout": "simple", "type": "boolean" },
"@out-of-print": { "type": "boolean" },
"@Q{http://www.w3.org/2001/XMLSchema-instance}nil": { "type": "skip" }
}xsi namespaceThis section defines modifications to the above rules that apply to elements having attributes in the xsi namespace (that is, http://www.w3.org/2001/XMLSchema-instance).
When analyzing a corpus using fn:element-to-map-plan, elements having the attribute xsi:nil="true" are ignored. If all elements with a given name have this attribute, allocate the layout mixed.
When deciding whether an element has any attributes (for example to decide between the layouts empty and empty-plus), all attributes in the xsi namespace are ignored.
When converting an individual element to a map, all attributes in the xsi namespace are ignored.
Notwithstanding the above, elements having the nilled property (which essentially means they are schema-validated and have the attribute xsi:nil="true"), are treated specially by each of the possible element layouts.
This section provides a definition of the structure of the conversion plan that is output by the fn:element-to-map-plan function, and used as input to the fn:element-to-map function.
The structure is defined by the following item type:
map( xs:string,
record ( layout? as enum("empty", "empty-plus", "simple", "simple-plus",
"list", list-plus",
"record", "sequence", "mixed",
"xml", "error", "deep-skip"),
child? as xs:string,
type? as enum("boolean", "numeric", "string", "skip")
* )
)The rules relating to this structure are as follows:
The keys of the map entries are strings of the form:
local-name representing the name of an element in no namespace.
Q{uri}local-name representing the name of an element in a namespace.
* representing a fallback rule for use with elements where either (a) there is no more specific rule, or (b) processing using the selected layout fails.
@local-name representing the name of an attribute in no namespace.
@Q{uri}local-name representing the name of an attribute in a namespace.
Any entries whose keys are not in this format will be ignored.
The layout entry is present if and only if the key represents the name of an element.
The child entry is present if and only if the value of layout is list or list-plus. It represents an element name in the format local-name for a name in no namespace, or Q{uri}local-name for a name in a namespace.
The type entry is present if, and only if, one of the following conditions applies:
The key represents the name of an attribute.
The layout is simple or simple-plus. In this case the value must not be "skip".
If additional entries (beyond those described above) are present in any of the maps, they are ignored, provided that the map is coercible to the given type definition.
The fallback rule (with key "*") is used to process elements whose name has no specific entry, and also for elements where normal processing fails (for example when the selected layout is "empty", but the element has children). If no fallback rule is present then "error" is assumed: this causes processing to fail with a dynamic error. The fallback rule will typically set the layout property to one of the following:
error: this causes the function to fail with a dynamic error.
deep-skip: this causes the element and its content (recursively) to be omitted from the output.
mixed: this causes the element to be output using layout mixed
xml: this outputs the element to be output using layout xml, which represents the content as a string containing serialized XML.
However, any layout may be used as the fallback; if it fails, the error is unrecoverable.
As an alternative to constructing a conversion plan by analyzing a corpus of specimen documents, conversion may be controlled using type annotations derived from schema validation.
If the function element-to-map encounters an element whose name is not present in the conversion plan (including the case where no plan is supplied), and if the element has a type annotation T other than xs:anyType or xs:untyped, then the following rules apply:
Note:
This section uses the notation {prop} to refer to properties of schema components, as defined in [XSD 1.1 Part 1]. The schema component model from XSD 1.1 is used; when XSD 1.0 is used for validation, some properties such as {open content} will inevitably be absent.
Let zeroLength(ST) be true for a simple type ST if any of the following conditions is true:
ST.{variety} = list, and ST.{facets} includes a length or maxLength facet whose value is 0 (zero).
ST.{variety} = atomic, and ST.{facets} includes a length or maxLength facet whose value is 0 (zero).
ST.{variety} = atomic, and ST.{facets} includes an enumeration facet constraining the value to be zero-length.
ST.{variety} = atomic, and ST.{facets} includes a pattern facet with the value "" (a zero-length string).
If T is a simple type:
If zeroLength(T), then the selected layout is empty (see 14.5.1.1 Layout: Empty Content).
Otherwise, the selected layout is simple (see 14.5.1.3 Layout: Simple Content), and the selected type is boolean if T is derived from xs:boolean; numeric if T is derived from xs:decimal, xs:double, or xs:float; or string otherwise.
Otherwise (if T is a complex type):
Let $noAttributes be true if T.{attribute uses} is empty and T.{attribute wildcard} is absent.
If T.{content type}.{variety} = empty, then:
If $noAttributes and if empty layout is not disabled, then the selected layout is empty (see 14.5.1.1 Layout: Empty Content).
Otherwise, the selected layout is empty-plus (see 14.5.1.2 Layout: Empty Content with Attributes).
If T.{content type}.{variety} = simple (a complex type with simple content), then:
Let ST be T.{content type}.{simple type definition} (the corresponding simple type).
If zeroLength(ST), then:
If $noAttributes, the selected layout is empty (see 14.5.1.1 Layout: Empty Content).
Otherwise, the selected layout is empty-plus (see 14.5.1.2 Layout: Empty Content with Attributes).
Otherwise:
If $noAttributes, the selected layout is simple (see 14.5.1.3 Layout: Simple Content).
Otherwise the selected layout is simple-plus (see 14.5.1.4 Layout: Simple Content with Attributes).
In both cases the selected type is one of booleannumeric, or string, chosen in the same way as for elements having a simple type.
If T.{content type}.{variety} = element-only (a complex type with an element-only content model):
Let $noWildcards be true if T.{content type}.{open content} is absent, and T.{content type}.{particle}, expanded recursively, contains no wildcard term.
Let $childCardinalities be a set of (xs:QName, xs:double) pairs representing the expanded names of the element declaration terms within T.{content type}.{particle}, expanded recursively, and for each one, the maximum number of occurrences of elements with that name, computed using the value of the {maxOccurs} property of the particles at each level, taking the value unbounded as positive infinity.
If $noWildcards is true, and if $childCardinalities contains a single entry, and that entry has a cardinality greater than one, then:
If $noAttributes then the selected layout is list (see 14.5.1.5 Layout: Simple List).
Otherwise, the selected layout is list-plus (see 14.5.1.6 Layout: List with Attributes).
If $noWildcards is true, and if every entry in $childCardinalities has a cardinality of one, then the selected layout is record (see 14.5.1.7 Layout: Record).
Otherwise, the selected layout is sequence (see 14.5.1.8 Layout: Sequence).
Otherwise (that is, when T.{content type}.{variety} = mixed, the selected layout is mixed (see 14.5.1.9 Layout: Mixed).
For attribute nodes, the selected type is boolean if the type annotation is derived from xs:boolean; numeric if the type annotation is derived from xs:decimal, xs:double, or xs:float; and string otherwise.
The various layouts available for elements are described in 14.5.1 Element Layouts. This section defines the rules for selecting an element layout for a given element E. The rules are applied in order.
If an explicit layout is given for the element name of E in the conversion plan supplied to the fn:element-to-map function call, then that layout is used. If the selected layout is deep-skip, then no output is produced for that element. If the selected layout is error, then the function fails with a dynamic error. If the selected layout fails for the element instance, then the fallback layout (identified with the key "*" in the conversion plan) is used; in the absence of a fallback layout, the function fails with a dynamic error.
Otherwise (when no explicit layout is given for E), if the type annotation of the element is something other than xs:untyped or xs:anyType, then a schema-determined layout is used as defined in 14.5.514.5.4 Schema-based conversion.
Otherwise, if the conversion plan supplies a fallback layout (identified with the key "*"), then the fallback layout is used.
If the above rules do not provide a layout for E, then a conversion plan for E is determined by applying the rules in 14.5.2 Creating a conversion plan, with an input that contains the single element E and no others. (Only the element E itself is considered, not its descendants.)
The name-format option gives control over how element and attribute names are formatted. There are four options:
The default option (which may be explicitly requested by specifying "name-format": "default") retains the namespace URI for any element that is either (a) the top-level element of a tree being converted, or (b) has a name that is in a different namespace from its parent element. In such cases the format "Q{uri}local" is used. For other elements, the name is output using the local part of the element name alone. For attributes, the form "Q{uri}local" is used for an attribute in a namespace, and the local name alone is used for a no-namespace name. Namespace prefixes are not retained.
The option eqname uses the format "Q{uri}local" for all element and attribute names that are in a namespace, or the local name alone for all names that are not in a namespace.
The option local discards all namespace information: all elements and attributes are output using the local name alone.
The option lexical outputs element and attribute names in the form obtained by calling the function fn:name. If the name has a prefix, the prefix is retained in the output. However, the output contains no information that enables the prefix to be associated with a namespace URI, so this format is suitable only when prefixes in the input documents are used predictably.
Regardless of the chosen name-format, and regardless of the above rules, attributes in the xml namespace (http://www.w3.org/XML/1998/namespace) are output using a lexical QName, with the prefix xml.
Attribute names in the output are typically prefixed with the character "@". The option attribute-marker allows this to be changed to a different prefix or none.
Whichever format of names is chosen, if the rules for the selected layout would result in an output map having two entries with the same key, the conflict is resolved by combining these entries into an array. For example if name-format is set to local then the element <data x:val="3" y:val="4"/> becomes either { "data": { "@val": ["3", "4"] } } or (because attribute order is unpredictable) { "data": { "@val": ["4", "3"] } }.
The conversion plan may indicate that element content is to be output as type string, numeric, or boolean: the default is string. In the case of untyped elements and attributes, the value is output as an instance of a string, numeric, or boolean type, according to this prescription. Specifically:
If the prescribed type is boolean and the value is castable as xs:boolean, then it is output as an instance of xs:boolean.
If the prescribed type is numeric and the value is castable as xs:numeric, then it is output as an instance of xs:integer, xs:decimal, or xs:double depending on the lexical form of the value, following the same rules as for XPath numeric literals. For example, "-1" becomes an xs:integer, 12.00 becomes an xs:decimal, and 1e-3 becomes an xs:double. The special xs:double values NaN and INF (which cannot be used as numeric literals) are also recognized.
In all other cases the value is output as an instance of xs:untypedAtomic, retaining its original lexical form.
Where the element or attribute is schema-validated, however:
If an element has the nilled property (that is, xsi:nil="true"), then the mapping for nilled elements with the chosen layout is used.
Let AV be the typed value of the node (that is, the result of atomization).
If, however, an element is annotated with a type that does not allow atomization (specifically, a complex type with element-only content) then let AV be the string value of the element, as an atomic item of type xs:untypedAtomic.
If an attribute is annotated as having a simple type of {variety} list, or if an element using layout simple or simple-plus is annotated as having either a simple type of {variety} list or a complex type with simple content of {variety} list then the atomized value AV is represented in the result as the array represented by the XPath expression array{AV}. This applies whether or not the atomized value actually contains multiple atomic items. The individual atomic items in the array retain their type, for example items of type xs:date remain items of type xs:date in the result.
In all other cases AV will be a single atomic item, and this value is used as is, retaining its type.
Note:
Atomic items in the result of the fn:element-to-map function may thus be of any atomic type. The type information is lost if the result is subsequently serialized as JSON.
This section is non-normative. Its purpose is to explain what information available in the XDM nodes supplied as input to the fn:element-to-map function is missing from the output.
Element and attribute names: If the chosen name-format is default or eqname, then local names and namespace URIs of elements and attributes are retained, but namespace prefixes are lost. If the chosen name-format is lexical, then prefixes are retained but namespace URIs are lost. If the chosen name-format is local then only local names are retained; namespace URIs and prefixes are lost.
In addition, element names are lost when the parent element is mapped using list layout: see 14.5.1.5 Layout: Simple List.
In-scope namespaces: All information about in-scope namespaces (and in particular, bindings for namespaces that are declared but not used in element and attribute names) is lost.
Comments and processing instructions: Comments and processing instructions are lost except when they appear as children of elements that are mapped using the sequence, mixed or xml layouts.
Text nodes: Whitespace text nodes are discarded when they appear as children of elements that are mapped using the empty, empty-plus, list, list-plus, record, or sequence layouts. Non-whitespace text nodes are never discarded.
Additional node properties: The values of the is-id, is-idref, and is-nilled properties of a node are lost.
Type annotations: The values of type annotations on elements are lost. Type annotations on atomized values of schema-validated nodes, however, are retained.
Element order: The order of child elements is lost when record layout is used and the element has multiple children with the same name.
XSI attributes: Attributes in the xsi namespace (for example, xsi:type and xsi:nil) are not represented in the result. .
The following examples show the effect of transforming some simple XML documents with default options, and then serializing the result as JSON with indent is set to true. The actual indentation is implementation dependent.
| XDM element | JSON serialization of result |
|---|---|
<a x='1' b='2'/> | { "a":{
"@x": "1",
"@b": "2"
} } |
<a><x>1</x><y>2</y></a> | { "a":{
"x": "1",
"y": "2"
} } |
<polygon> <point x='0' y='0'/> <point x='0' y='1'/> <point x='1' y='1'/> <point x='1' y='0'/> </polygon> | { "polygon":[
{"@x": "0", "@y": "0"},
{"@x": "0", "@y": "1"},
{"@x": "1", "@y": "1"},
{"@x": "1", "@y": "0"}
] ] } |
<cities>
<city id="LDN">
<name>London</name>
<size>18.2</size>
</city>
<city id="PRS">
<name>Paris</name>
<size>19.1</size>
</city>
<city id="BLN">
<name>Berlin</name>
<size>14.6</size>
</city>
</cities> | { "cities":[
{
"@id": "LDN",
"name": "London",
"size": "18.2"
},
{
"@id": "PRS",
"name": "Paris",
"size": "19.1"
},
{
"@id": "BLN",
"name": "Berlin",
"size": "14.6"
}
] } |
The following more complex example demonstrates a case where the default conversion is inadequate (for example, it wrongly assumes that for the third production, the order of child elements is immaterial). A better result, shown below, can be achieved by using a schema-aware conversion.
| XDM element | JSON serialization of result |
|---|---|
<g:grammar language="xquery"
xmlns:g="http://www.w3.org/XPath/grammar">
<g:production
name="FunctionBody">
<g:ref name="EnclosedExpr"/>
<g:ref name="Block"/>
</g:production>
<g:production
name="EnclosedExpr">
<g:ref name="Lbrace"/>
<g:ref name="Expr"/>
<g:optional>
<g:ref name="Expr"/>
</g:optional>
<g:ref name="Rbrace"/>
</g:production>
<g:production
name="SimpleReturnClause">
<g:string>return</g:string>
<g:ref name="ExprSingle"/>
</g:production>
</g:grammar> | [{ "Q{http://www.w3.org/XPath/grammar}grammar": [
{ "@language": "xquery" },
{ "production": [
{ "@name": "FunctionBody" },
{ "ref": { "@name": "EnclosedExpr" } },
{ "ref": { "@name": "Block" } }
] },
{ "production": [
{ "@name": "EnclosedExpr" },
{ "ref": { "@name": "Lbrace" } },
{ "ref": { "@name": "Expr" } },
{ "optional":[
{ "ref": { "@name": "Expr" } }
] },
{ "ref": { "@name": "Rbrace" } }
] },
{ "production": [
{ "@name": "SimpleReturnClause" },
{ "string": "return" },
{ "ref": { "@name": "ExprSingle" } }
] }
] }] |
Note:
In the above example, the schema used to validate the source document was simplified to eliminate options that do not actually arise in this input instance (such as the g:string element having attributes). This is a legitimate technique that may be useful when trying to obtain the simplest possible JSON representation.
Further improvements to the usability of the JSON output could be achieved by doing some simple transformation of the XML prior to conversion. For example, the name attribute of various productions could be converted to a child element, and <ref name="x"/> could be transformed to <ref>x</ref>.
Analyzes sample data to generate a conversion plan suitable for use by the element-to-map function.
fn:element-to-map-plan( | ||
$input | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
The function takes as input a collection of document and element nodes and analyzes the trees rooted at these nodes to determine a conversion plan for converting elements in these trees to maps, suitable for serialization in JSON format. The conversion plan can be used as-is by supplying it directly to the element-to-map function; alternatively it can be amended before use. The plan can also be serialized to a file (in JSON format) allowing the same plan to be used repeatedly for transforming documents with a similar structure to those in the sample provided.
The rules followed by the function, and the detailed format of the conversion plan, are described in 14.5.2 Creating a conversion plan.
The effect of the function is equivalent to the result of the following XQuery expression.
let $data-type := fn($nodes as node()*) {
if (every($nodes ! (. castable as xs:boolean))) then "boolean"
else if (every($nodes ! (. castable as xs:numeric))) then "numeric"
else ()
}
let $name := fn($node as node()) {
if (namespace-uri($node))
then expanded-QName(node-name($node))
else local-name($node)
}
return (
for $ee in $input/descendant-or-self::*
group by $n := $name($ee)
return { $n :
if (empty($ee/(*|text())))
then { 'layout' : if (empty($ee/@*))
then 'empty'
else 'empty-plus' }
else if (empty($ee/*))
then map:merge((
if (empty($ee/@*))
then {'layout': 'simple'}
else {'layout': 'simple-plus'},
$data-type($ee) ! { 'type': . }
))
else if (empty($ee/text()[normalize-space()]))
then if (all-equal($ee/*/node-name()) and exists($ee/*[2]))
then { 'layout': if (empty($ee/@*))
then 'list'
else 'list-plus',
'child': $name(head($ee/*))
}
else { 'layout' : if (every($ee ! all-different(*/node-name())))
then 'record'
else 'sequence'
}
else {'layout': 'mixed'}
},
for $a in $input//@*
group by $n := $name($a)
let $t := $data-type($a)
return $t ! { `@{$n}`: { 'type': $t } }
) => map:merge()The conversion plan is organized by element and attribute name, so its effectiveness depends on the $input collection being homogenous in its structure, and representative of the documents that will subsequently be converted using the element-to-map function.
This function is separate from the element-to-map function for a number of reasons:
The collection of documents that need to be analyzed to establish an effective conversion plan might be much smaller than the set of documents actually being converted.
Conversely, it might be that only a small number of documents need to be converted at a particular time, but the conversion plan used needs to take into account variations that might exist within a larger corpus.
If JSON output is required in a particular format, it might be necessary to fine-tune the automatically generated conversion plan to take account of these requirements.
It might be necessary to devise a conversion plan that can be used to convert individual documents as they arrive over a period of time, and to ensure that the same conversion rules are applied to each document even though documents might exhibit variations in structure.
The conversion plan is human-readable, which can help in understanding why the output of element-to-map is in a particular form.
| Expression: | element-to-map-plan(<a><b>3</b><b>4</b></a>) |
|---|---|
| Result: | { 'a': { 'layout': 'list', 'child': 'b' },
'b': { 'layout': 'simple', 'type': 'numeric' }
} |
| Expression: | element-to-map-plan((<a x="2">red</a>, <a x="3">blue</a>)) |
| Result: | { 'a': { 'layout': 'simple-plus' },
'@x': { 'type': 'numeric' }
} |
| Expression: | element-to-map-plan( <a xmlns="http://example.ns">H<sub>2</sub>SO<sub>4</sub></a> ) |
| Result: | { 'Q{http://example.ns}a': { 'layout': 'mixed' },
'Q{http://example.ns}sub': { 'layout': 'simple', 'type': 'numeric' }
} |
| Expression: | element-to-map-plan((<a><b/><b/></a>, <a><b/><c/></a>)) |
| Result: | { 'a': { 'layout': 'sequence' },
'b': { 'layout': 'empty' },
'c': { 'layout': 'empty' }
} |
Converts an element node into a map that is suitable for JSON serialization.
fn:element-to-map( | ||
$element | as , | |
$options | as | := {} |
) as | ||
This function is deterministic, context-independent, and focus-independent.
This function returns a map derived from the element node supplied in $element. The map is in a form that is suitable for JSON serialization, thus providing a mechanism for conversion of arbitrary XML to JSON.
The map that is returned will always be a single-entry map; the key of this entry will be a string representing the element name, and the value of the entry will be a representation of the element's attributes and children.
The entries that may appear in the $options map are as follows. The option parameter conventions apply.
record( | |
plan? | as map(xs:string, record(layout?, child?, type?)), |
attribute-marker? | as xs:string, |
name-format? | as xs:string |
) | |
| Key | Value | Meaning |
|---|---|---|
| A conversion plan, supplied as a map whose keys represent element and attribute names. The plan might be generated using the function element-to-map-plan, or it might be constructed in some other way. The format of the plan is described in 14.5.2 Creating a conversion plan.
| |
| A string that is prepended to any key value in the output that represents an XDM attribute node in the input. The string may be empty. If, after applying the requested prefix (or no prefix) there is a conflict between the names of attributes and child elements, then the requested prefix (or lack thereof) is ignored and the default prefix "@" is used.
| |
| Indicates how the names of element and attribute nodes are handled.
| |
lexical | Names are output in the form produced by the fn:name function. | |
local | Names are output in the form produced by the fn:local-name function. | |
eqname | Names in a namespace are output in the form "Q{uri}local". Names in no namespace are output using the local name alone. | |
default | An element name is output as a local name alone if either (a) it is a top-level element and is in no namespace, or (b) it is in the same namespace as its parent element. An attribute name is output as a local name alone if it is in no namespace. All other names are output in the format "Q{uri}local" if in a namespace, or "Q{}local" if in no namespace. "Top-level" here means that the element is one that appears explicitly in the sequence of elements passed in the $elements argument, as distinct from a descendant of such an element. | |
If $element is the empty sequence, the result is the empty sequence.
The principles for conversion from elements to maps are described in 14.5.1 Element Layouts, and the rules for selecting an element layout for each element are given in 14.5.614.5.5 Selecting an element layout.
In general, every descendant element within the tree rooted at the supplied $element maps to a key-value pair in which the key represents the element name, and the corresponding value represents the attributes and children of the element. This key-value pair will be added to the content representing its parent element, in a way that depends on the parent element's layout.
The representation of a node of any other kind depends on the layout chosen for its parent element.
A dynamic error [err:FOJS0008] occurs if any element cannot be processed using the selected layout for that element, unless fallback processing is defined; or if error action is explicitly requested for an element.
Any error in the conversion plan is treated as a type error [err:XPTY0004]XP whether or not it is technically a contravention of the defined type for the value. This relieves users and implementers of the burden of distinguishing different kinds of error in the plan.
| Expression: |
|
|---|---|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: | element-to-map(
<list>
<item value='1'/>
<item value='2'/>
</list>, { 'attribute-marker': '' }
) |
| Result: | { "list": [
{ "value": "1" },
{ "value": "2" }
] } |
| Expression: | element-to-map(
<name>
<first>Jane</first>
<last>Smith</last>
</name>
) |
| Result: | { "name": {
"first": "Jane",
"last": "Smith"
} } |
| Expression: | element-to-map(
<name xmlns="http://example.ns/">
<first>Jane</first>
<middle>Elizabeth</middle>
<middle>Mary</middle>
<last>Smith</last>
</name>,
{ 'plan': {'Q{http://example.ns/}name': { 'layout': 'record' }},
'name-format' : 'local'
}
) |
| Result: | { "name": {
"first": "Jane",
"middle": ["Elizabeth", "Mary"],
"last": "Smith"
}
} |
| Expression: | element-to-map(
<name xmlns="http://example.ns/">
<first>Jane</first>
<middle>Elizabeth</middle>
<middle>Mary</middle>
<last>Smith</last>
</name>,
{ 'plan': {'Q{http://example.ns/}name': { 'layout': 'record' },
'Q{http://example.ns/}middle': { 'layout': 'deep-skip' }
},
'name-format' : 'local'
}
) |
| Result: | { "name": {
"first": "Jane",
"last": "Smith"
}
} |
This section is non-normative.
Because a map is a function item, functions that apply to functions also apply to maps. A map is an anonymous function, so fn:function-name returns the empty sequence; fn:function-arity always returns 1.
Maps may be compared using the fn:deep-equal function.
There is no function or operator to atomize a map or convert it to a string (other than fn:serialize, which can be used to serialize some maps as JSON texts).
XPath 4.0 defines a number of syntactic constructs that operate on maps. These all have equivalents in the function library:
The expression {} creates the empty map (see [XML Path Language (XPath) 4.0] section 4.15.1.14.14.1.1 Map Constructors). This is equivalent to the effect of the data model primitive dm:empty-map(). Using user-visible functions the same can be achieved by calling map:build or map:merge, supplying the empty sequence as the argument.
The map constructor { K1 : V1, K2 : V2, ... , Kn : Vn } is equivalent to map:merge((map:entry(K1, V1), map:entry(K1, V1), ..., map:entry(Kn, Vn)), { "duplicates": "reject" })
The lookup expression $map?* (see [XML Path Language (XPath) 4.0] section 4.15.34.14.3 Lookup Expressions) is equivalent to map:items($map).
The lookup expression $map?K, where K is a key value, is equivalent to map:get($map, K)
The expression for key $k value $v in $map return EXPR (see [XQuery 4.0: An XML Query Language] section 4.13.2 For Clause and [XML Path Language (XPath) 4.0] section 4.14.14.13.1 For Expressions) is equivalent to the function call map:for-each($map, fn($k, $v) { EXPR }).
Maps can be filtered using the construct $map?[predicate] (see [XML Path Language (XPath) 4.0] section 4.15.54.14.5 Filter Expressions for Maps and Arrays).
Arrays were introduced as a new datatype in XDM 3.1. This section describes functions that operate on arrays.
An array is an additional kind of item. An array of size N is a mapping from the integers (1 to N) to a set of values, called the members of the array, each of which is an arbitrary sequence. Because an array is an item, and therefore a sequence, arrays can be nested.
An array acts as a function from integer positions to associated values, so the function call $array($index) can be used to retrieve the array member at a given position. The function corresponding to the array has the signature function($index as xs:integer) as item()*. The fact that an array is a function item allows it to be passed as an argument to higher-order functions that expect a function item as one of their arguments.
This section is non-normative.
Arrays may be compared using the fn:deep-equal function.
The XPath language provides explicit syntax for certain operations on arrays. These constructs can all be specified in terms of function primitives:
The empty array can be constructed using either of the expressions [] or array{}. The effect is the same as the data model primitive dm:empty-array(()) (see [XML Path Language (XPath) 4.0] section 4.15.2.14.14.2.1 Array Constructors). Using user-visible functions it can be achieved by calling array:build(()) or array:of-members(()).
The expression array { $sequence } constructs an array whose members are the items in $sequence. Every member of this array will be a singleton item. The effect is the same as array:build($sequence).
The expression [E1, E2, E3, ..., En] constructs an array in which E1 is the first member, E2 is the second member, and so on. The result is equivalent to the expression [] => array:append(E1) => array:append(E2) => ... => array:append(En))).
The lookup expression $array?* returns the sequence concatenationXP of the members of the array. It is equivalent to calling array:fold-left($array, (), fn($result, $next){ $result, $next }).
The lookup expression $array?$N, where $N is an integer within the bounds of the array, is equivalent to array:get($array, $N).
Similarly, applying the array as a function, $array($N), is also equivalent to array:get($array, [$N])
The expression for member $m in $array return EXPR is equivalent to array:for-each($array, fn($m){ EXPR }) (see [XQuery 4.0: An XML Query Language] section 4.13.2 For Clause and [XML Path Language (XPath) 4.0] section 4.14.14.13.1 For Expressions).
Arrays can be filtered using the construct $array?[predicate] (see [XML Path Language (XPath) 4.0] section 4.15.54.14.5 Filter Expressions for Maps and Arrays).
Constructor functions are used to convert a supplied value to a given type, and the name of the function is the same as the name of the target type. This section describes constructor functions corresponding to the following types:
Simple types (atomic types, union types, and list types as defined in [XML Schema Part 2: Datatypes Second Edition]), which are present in the static context either because they appear in the in-scope schema typesXP or because they appear as named item typesXP.
These constructor functions always take a single argument.
Record types defined as named item typesXP.
These take one argument for each named field of the record type. Constructor functions for record types are defined in 22.6 Constructor functions for named record types.
Constructor functions are defined for all user-defined named simple types, and for most built-in atomic, list, and union types. The only named simple types that have no constructor function are those that have no instances other than instances of their derived types: specifically, xs:anySimpleType, xs:anyAtomicType, and xs:NOTATION.
Every built-in atomic type that is defined in [XML Schema Part 2: Datatypes Second Edition], except xs:anyAtomicType and xs:NOTATION, has an associated constructor function. The type xs:untypedAtomic, defined in 2.7 Schema Information DM31 and the two derived types xs:yearMonthDuration and xs:dayTimeDuration defined in 2.7 Schema Information DM31 also have associated constructor functions. Implementations may additionally provide a constructor functions for the new datatype xs:dateTimeStamp introduced in [XSD 1.1 Part 2].
A constructor function is not defined for xs:anyAtomicType as there are no atomic items with type annotation xs:anyAtomicType at runtime, although this can be a statically inferred type. A constructor function is not defined for xs:NOTATION since it is defined as an abstract type in [XML Schema Part 2: Datatypes Second Edition]. If the static context (See 2.1.1 Static Context XP31) contains a type derived from xs:NOTATION then a constructor function is defined for it. See 22.5 Constructor functions for user-defined atomic and union types.
The form of the constructor function for an atomic type eg:TYPE is:
eg:TYPE( | ||
$value | as | := . |
) as | ||
If $arg is the empty sequence, the empty sequence is returned. For example, the signature of the constructor function corresponding to the xs:unsignedInt type defined in [XML Schema Part 2: Datatypes Second Edition] is:
xs:unsignedInt( | ||
$arg | as | := . |
) as | ||
Calling the constructor function xs:unsignedInt(12) returns the xs:unsignedInt value 12. Another call of that constructor function that returns the same xs:unsignedInt value is xs:unsignedInt("12").
The same result would also be returned if the constructor function were to be called with a node that had a typed value equal to the xs:unsignedInt 12. Because the declared parameter type for the argument is xs:anyAtomicType?, the coercion rules will atomize the supplied argument (see 2.4.2 Atomization XP31) to extract its typed value and then call the constructor with the atomized value.
Calling the constructor function xs:unsignedInt(12) returns the xs:unsignedInt value 12. Another call of that constructor function that returns the same xs:unsignedInt value is xs:unsignedInt("12"). The same result would also be returned if the constructor function were to be called with a node that had a typed value equal to the xs:unsignedInt 12. The standard features described in 2.4.2 Atomization XP31 would atomize the node to extract its typed value and then call the constructor with that value. If the value passed to a constructor function, after atomization, is not in the lexical space of the datatype to be constructed, and cannot be converted to a value in the value space of the datatype under the rules in 23 Castingthis specification, then an dynamic error is raised [err:FORG0001].
The semantics of the constructor function xs:TYPE(arg) are identical to the semantics of arg cast as xs:TYPE? . See 23 Casting.
If the argument to a constructor function is a literal, the result of the function may be evaluated statically; if an error is found during such evaluation, it may be reported as a static error.
Special rules apply to constructor functions for xs:QName and types derived from xs:QName and xs:NOTATION. See 22.2 Constructor functions for xs:QName and xs:NOTATION.
The argument is optional, and defaults to the context value (which will be atomized if necessary).
The following constructor functions for the built-in atomic types are supported:
xs:string( | ||
$value | as | := . |
) as | ||
xs:boolean( | ||
$value | as | := . |
) as | ||
xs:decimal( | ||
$value | as | := . |
) as | ||
xs:float( | ||
$value | as | := . |
) as | ||
Implementations should return negative zero for xs:float("-0.0E0"). But because [XML Schema Part 2: Datatypes Second Edition] does not distinguish between the values positive zero and negative zero, implementations may return positive zero in this case.
xs:double( | ||
$value | as | := . |
) as | ||
Implementations should return negative zero for xs:double("-0.0E0"). But because [XML Schema Part 2: Datatypes Second Edition] does not distinguish between the values positive zero and negative zero, implementations may return positive zero in this case.
xs:duration( | ||
$value | as | := . |
) as | ||
xs:dateTime( | ||
$value | as | := . |
) as | ||
xs:time( | ||
$value | as | := . |
) as | ||
xs:date( | ||
$value | as | := . |
) as | ||
xs:gYearMonth( | ||
$value | as | := . |
) as | ||
xs:gYear( | ||
$value | as | := . |
) as | ||
xs:gMonthDay( | ||
$value | as | := . |
) as | ||
xs:gDay( | ||
$value | as | := . |
) as | ||
xs:gMonth( | ||
$value | as | := . |
) as | ||
xs:hexBinary( | ||
$value | as | := . |
) as | ||
xs:base64Binary( | ||
$value | as | := . |
) as | ||
xs:anyURI( | ||
$value | as | := . |
) as | ||
xs:QName( | ||
$value | as | := . |
) as | ||
See 22.2 Constructor functions for xs:QName and xs:NOTATION for special rules.
xs:normalizedString( | ||
$value | as | := . |
) as | ||
xs:token( | ||
$value | as | := . |
) as | ||
xs:language( | ||
$value | as | := . |
) as | ||
xs:NMTOKEN( | ||
$value | as | := . |
) as | ||
xs:Name( | ||
$value | as | := . |
) as | ||
xs:NCName( | ||
$value | as | := . |
) as | ||
xs:ID( | ||
$value | as | := . |
) as | ||
xs:IDREF( | ||
$value | as | := . |
) as | ||
xs:ENTITY( | ||
$value | as | := . |
) as | ||
See 23.1.10 Casting to xs:ENTITY for rules related to constructing values of type xs:ENTITY and types derived from it.
xs:integer( | ||
$value | as | := . |
) as | ||
xs:nonPositiveInteger( | ||
$value | as | := . |
) as | ||
xs:negativeInteger( | ||
$value | as | := . |
) as | ||
xs:long( | ||
$value | as | := . |
) as | ||
xs:int( | ||
$value | as | := . |
) as | ||
xs:short( | ||
$value | as | := . |
) as | ||
xs:byte( | ||
$value | as | := . |
) as | ||
xs:nonNegativeInteger( | ||
$value | as | := . |
) as | ||
xs:unsignedLong( | ||
$value | as | := . |
) as | ||
xs:unsignedInt( | ||
$value | as | := . |
) as | ||
xs:unsignedShort( | ||
$value | as | := . |
) as | ||
xs:unsignedByte( | ||
$value | as | := . |
) as | ||
xs:positiveInteger( | ||
$value | as | := . |
) as | ||
xs:yearMonthDuration( | ||
$value | as | := . |
) as | ||
xs:dayTimeDuration( | ||
$value | as | := . |
) as | ||
xs:untypedAtomic( | ||
$value | as | := . |
) as | ||
xs:dateTimeStamp( | ||
$value | as | := . |
) as | ||
Available only if the implementation supports XSD 1.1.
If a section of this specification has been updated since version 3.1, an overview of the changes is provided, along with links to navigate to the next or previous change.
See 1 Introduction
Sections with significant changes are marked with a ✭ symbol in the table of contents. New functions are indicated by ✚.
See 1 Introduction
PR 1504 2329
New in 4.0
New in 4.0
New in 4.0
See 2.1.12 fn:slice
PR 1120 1150
A callback function can be supplied for comparing individual items.
Changed in 4.0 to use transitive equality comparisons for numeric values.
PR 614 987
New in 4.0
New in 4.0. Originally proposed under the name fn:uniform
New in 4.0. Originally proposed under the name fn:unique
New in 4.0
See 2.5.3 fn:every
New in 4.0
See 2.5.9 fn:highest
New in 4.0
New in 4.0
See 2.5.11 fn:lowest
New in 4.0
New in 4.0
See 2.5.16 fn:some
PR 795 2228
New in 4.0
PR 521 761
New in 4.0
New in 4.0
See 4.4.5 fn:is-NaN
PR 1260 1275
A third argument has been added, providing control over the rounding mode.
See 4.4.6 fn:round
PR 1049 1151
Decimal format parameters can now be supplied directly as a map in the third argument, rather than referencing a format defined in the static context.
PR 1205 1230
New in 4.0
See 4.8.2 math:e
See 4.8.8 math:cosh
See 4.8.15 math:sinh
See 4.8.18 math:tanh
The 3.1 specification suggested that every value in the result range should have the same chance of being chosen. This has been corrected to say that the distribution should be arithmetically uniform (because there are as many xs:double values between 0.01 and 0.1 as there are between 0.1 and 1.0).
PR 261 306 993
New in 4.0
See 5.4.1 fn:char
New in 4.0
PR 937 995 1190
New in 4.0
See 5.4.13 fn:hash
PR 215 415
New in 4.0
PR 1423 1413
New in 4.0
New in 4.0
New in 4.0
New in 4.0
PR 1620 1886
Options are added to customize the form of the output.
See 12.2.9 fn:path
PR 1547 1551
New in 4.0
PR 969 1134
New in 4.0
PR 478 515
New in 4.0
PR 1575 1906
A new function fn:element-to-map is provided for converting XDM trees to maps suitable for serialization as JSON. Unlike the fn:xml-to-json function retained from 3.1, this can handle arbitrary XML as input.
New in 4.0
PR 968 1295
New in 4.0
PR 476 1087
New in 4.0
PR 360 476
New in 4.0
Supplying the empty sequence as the value of an optional argument is equivalent to omitting the argument.
PR 1117 1279
The $options parameter has been added.
PR 259 956
A new function is available for processing input data in HTML format.
See 17.3 Functions on HTML Data
New in 4.0
An option is provided to control how JSON numbers should be formatted.
Additional options are available, as defined by fn:parse-json.
New in 4.0
New in 4.0
New in 4.0
PR 629 803
New in 4.0
PR 533 719 834
New functions are available for processing input data in CSV (comma separated values) format.
Comparison of mixed numeric types (for example xs:double and xs:decimal) now generally converts both values to xs:decimal.
PR 289 1901
A third argument is added, allowing user control of how absent keys should be handled.
See 14.4.9 map:get
A third argument is added, allowing user control of how index-out-of-bounds conditions should be handled.
A new collation URI is defined for Unicode case-insensitive comparison and ordering.
PR 1727 1740
It is no longer guaranteed that the new key replaces the existing key.
See 14.4.14 map:put
The group may remove this function, it is considered at risk.
PR 173
New in 4.0
See 18.4 fn:op
PR 203
New in 4.0
See 14.4.1 map:build
PR 207
New in 4.0
PR 222
New in 4.0
See 2.2.3 fn:contains-subsequence
PR 250
New in 4.0
See 2.1.3 fn:foot
See 2.1.15 fn:trunk
PR 258
New in 4.0
PR 313
The second argument can now be a sequence of integers.
See 2.1.9 fn:remove
PR 319
New in 4.0. The function replaces the internal op:same-key function in 3.1
PR 326
Higher-order functions are no longer an optional feature.
See 1.2 Conformance
PR 360
New in 4.0
PR 419
New in 4.0
PR 434
New in 4.0
The function has been extended to allow output in a radix other than 10, for example in hexadecimal.
PR 477
New in 4.0
PR 482
Deleted an inaccurate statement concerning the behavior of NaN.
PR 507
New in 4.0
PR 546
It is no longer automatically an error if the input contains a codepoint that is not valid in XML. Instead, the codepoint must be a permitted character. The set of permitted characters is implementation-defined, but it is recommended that all Unicode characters should be accepted.
See 5.2.1 fn:codepoints-to-string
It is no longer automatically an error if the resource (after decoding) contains a codepoint that is not valid in XML. Instead, the codepoint must be a permitted character. The set of permitted characters is implementation-defined, but it is recommended that all Unicode characters should be accepted.
The rules regarding use of non-XML characters in JSON texts have been relaxed.
See 17.4.3 JSON character repertoire
It is no longer automatically an error if the input contains a codepoint that is not valid in XML. Instead, the codepoint must be a permitted character. The set of permitted characters is implementation-defined, but it is recommended that all Unicode characters should be accepted.
PR 609
New in 4.0
PR 631
New in 4.0
PR 662
Constructor functions now have a zero-arity form; the first argument defaults to the context item.
PR 680
The case-insensitive collation is now defined normatively within this specification, rather than by reference to the HTML "living specification", which is subject to change. The collation can now be used for ordering comparisons as well as equality comparisons.
PR 702
The function can now take any number of arguments (previously it had to be two or more), and the arguments can be sequences of strings rather than single strings.
See 5.4.4 fn:concat
PR 710
New in 4.0
PR 727
It has been clarified that loading a module has no effect on the static or dynamic context of the caller.
PR 828
The $predicate callback function accepts an optional position argument.
See 2.5.4 fn:filter
The $action callback function accepts an optional position argument.
The $predicate callback function now accepts an optional position argument.
The $action callback function now accepts an optional position argument.
PR 881
The way that fn:min and fn:max compare numeric values of different types has changed. The most noticeable effect is that when these functions are applied to a sequence of xs:integer or xs:decimal values, the result is an xs:integer or xs:decimal, rather than the result of converting this to an xs:float or xs:double.
See 2.4.5 fn:max
See 2.4.6 fn:min
PR 901
The optional third argument can now be supplied as the empty sequence.
The third argument can now be supplied as the empty sequence.
The second argument can now be the empty sequence.
The optional second argument can now be supplied as the empty sequence.
The 3rd, 4th, and 5th arguments are now optional; previously the function required either 2 or 5 arguments.
All three arguments are now optional, and each argument can be set to the empty sequence. Previously if $description was supplied, it could not be empty.
See 21.1.1 fn:error
The $label argument can now be set to the empty sequence. Previously if $label was supplied, it could not be empty.
See 21.2.1 fn:trace
PR 905
The rule that multiple calls on fn:doc supplying the same absolute URI must return the same document node has been clarified; in particular the rule does not apply if the dynamic context for the two calls requires different processing of the documents (such as schema validation or whitespace stripping).
See 17.1.1 fn:doc
PR 909
The function has been expanded in scope to handle comparison of values other than strings.
See 2.2.2 fn:compare
PR 924
Rules have been added clarifying that users should not be allowed to change the schema for the fn namespace.
See D Schemas
PR 925
The decimal format name can now be supplied as a value of type xs:QName, as an alternative to supplying a lexical QName as an instance of xs:string.
PR 932
The specification now prescribes a minimum precision and range for durations.
PR 933
When comments and processing instructions are ignored, any text nodes either side of the comment or processing instruction are now merged prior to comparison.
PR 940
New in 4.0
PR 953
Constructor functions for named record types have been introduced.
PR 962
New in 4.0
PR 969
New in 4.0
See 14.4.3 map:empty
PR 984
New in 4.0
See 8.4.1 fn:seconds
PR 987
The order of results is now prescribed; it was previously implementation-dependent.
PR 1022
Regular expressions can include comments (starting and ending with #) if the c flag is set.
See 6.1 Regular expression syntax
See 6.2 Flags
PR 1028
An option is provided to control how the JSON null value should be handled.
PR 1032
New in 4.0
See 2.1.17 fn:void
PR 1046
New in 4.0
PR 1059
Use of an option keyword that is not defined in the specification and is not known to the implementation now results in a dynamic error; previously it was ignored.
See 1.7 Options
PR 1068
New in 4.0
PR 1072
The return type is now specified more precisely.
PR 1090
When casting from a string to a duration or time or dateTime, it is now specified that when there are more digits in the fractional seconds than the implementation is able to retain, excess digits are truncated. Rounding upwards (which could affect the number of minutes or hours in the value) is not permitted.
PR 1093
New in 4.0
PR 1117
The $options parameter has been added.
PR 1182
The $predicate callback function may return the empty sequence (meaning false).
See 2.5.3 fn:every
See 2.5.4 fn:filter
See 2.5.16 fn:some
PR 1191
The $options parameter has been added, absorbing the $collation parameter.
New in 4.0
PR 1250
For selected properties including percent and exponent-separator, it is now possible to specify a single-character marker to be used in the picture string, together with a multi-character rendition to be used in the formatted output.
PR 1257
The $options parameter has been added.
PR 1262
New in 4.0
PR 1265
The constraints on the result of the function have been relaxed.
PR 1280
As a result of changes to the coercion rules, the number of supplied arguments can be greater than the number required: extra arguments are ignored.
See 2.5.1 fn:apply
PR 1288
Additional error conditions have been defined.
PR 1296
New in 4.0
PR 1333
A new option is provided to allow the content of the loaded module to be supplied as a string.
PR 1353
An option has been added to suppress the escaping of the solidus (forwards slash) character.
PR 1358
New in 4.0
PR 1361
The term atomic value has been replaced by atomic item.
See 1.9 Terminology
PR 1393
Changes the function to return a sequence of key-value pairs rather than a map.
PR 1409
This section now uses the term primitive type strictly to refer to the 20 atomic types that are not derived by restriction from another atomic type: that is, the 19 primitive atomic types defined in XSD, plus xs:untypedAtomic. The three types xs:integer, xs:dayTimeDuration, and xs:yearMonthDuration, which have custom casting rules but are not strictly-speaking primitive, are now handled in other subsections.
See 23.1 Casting from primitive types to primitive types
The rules for conversion of dates and times to strings are now defined entirely in terms of XSD 1.1 canonical mappings, since these deliver exactly the same result as the XPath 3.1 rules.
See 23.1.2.2 Casting date/time values to xs:string
The rules for conversion of durations to strings are now defined entirely in terms of XSD 1.1 canonical mappings, since the XSD 1.1 rules deliver exactly the same result as the XPath 3.1 rules.
PR 1455
Numbers now retain their original lexical form, except for any changes needed to satisfy JSON syntax rules (for example, stripping leading zero digits).
PR 1473
New in 4.0
PR 1481
The function has been extended to handle other Gregorian types such as xs:gYearMonth.
See 9.6.1 fn:year-from-dateTime
See 9.6.2 fn:month-from-dateTime
The function has been extended to handle other Gregorian types such as xs:gMonthDay.
See 9.6.3 fn:day-from-dateTime
The function has been extended to handle other types including xs:time.
See 9.6.4 fn:hours-from-dateTime
See 9.6.5 fn:minutes-from-dateTime
The function has been extended to handle other types such as xs:gYearMonth.
PR 1523
New functions are provided to obtain information about built-in types and types defined in an imported schema.
New in 4.0
PR 1545
New in 4.0
PR 1565
The default for the escape option has been changed to false. The 3.1 specification gave the default value as true, but this appears to have been an error, since it was inconsistent with examples given in the specification and with tests in the test suite.
PR 1570
New in 4.0
PR 1587
New in 4.0
PR 1611
The spec has been corrected to note that the function depends on the implicit timezone.
See 2.2.2 fn:compare
PR 1671
New in 4.0.
PR 1687
New in 4.0
PR 1703
Ordered maps are introduced.
Enhanced to allow for ordered maps.
See 14.4.7 map:find
See 14.4.14 map:put
The order of entries in maps is retained.
PR 1711
It is explicitly stated that the limits for $precision are implementation-defined.
See 4.4.6 fn:round
PR 1727
For consistency with the new function map:build, the handling of duplicates may now be controlled by supplying a user-defined callback function as an alternative to the fixed values for the earlier duplicates option.
PR 1734
In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification was unclear whether it was permitted to add the first two integer items using integer arithmetic, rather than converting all items to doubles before performing any arithmetic. The 4.0 specification is clear that this is permitted; but since the items can be reordered before being added, this is not required.
See 2.4.4 fn:avg
See 2.4.7 fn:sum
PR 1801
New in 4.0
PR 1825
New in 4.0
PR 1856
Word boundaries can be matched. Lookahead and lookbehind assertions are supported. Assertions (including ^ and $) can no longer be followed by a quantifier.
See 6.1 Regular expression syntax
The output of the function is extended to allow the represention of captured groups found within lookahead assertions.
PR 1879
Additional options to control DTD and XInclude processing have been added.
PR 1897
The $replacement argument can now be a function that computes the replacement strings.
See 6.3.2 fn:replace
PR 1906
New in 4.0
See 14.5.1114.5.10 fn:element-to-map-plan
New in 4.0.
PR 1910
An $options parameter is added. Note that the rules for the $options parameter control aspects of processing that were implementation-defined in earlier versions of this specification. An implementation may provide configuration options designed to retain backwards-compatible behavior when no explicit options are supplied.
See 17.1.1 fn:doc
PR 1913
It is now permitted for the regular expression to match a zero-length string.
See 6.3.2 fn:replace
PR 1933
New in 4.0
PR 1991
Named record types used in the signatures of built-in functions are now available as standard in the static context.
PR 2001
New in 4.0.
PR 2013
Support for binary input has been added.
See 17.2.2 fn:parse-xml-fragment
New in 4.0
PR 2030
This description of the XSD validation process was previously found (with some duplication) in the XQuery and XSLT specifications; those specifications now reference this description. As a side-effects, the descriptions of the process in XQuery and XSLT are better aligned.
PR 2031
Introduced the concept of JNodes.
New in 4.0
See 16.1.1 fn:jtree
PR 2149
Generalized to work with JNodes as well as XNodes.
The function is extended to handle JNodes.
See 12.2.9 fn:path
Generalized to work with JNodes as well as XNodes.
PR 2168
Atomic items of types xs:hexBinary and xs:base64Binary are now mutually comparable. In rare cases, where an application uses both types and assumes they are distinct, this can represent a backwards incompatibility.
PR 2223
An error may now be raised if the base URI is not a valid LEIRI reference.
PR 2224
The $action callback function now accepts an optional position argument.
PR 2228
New in 4.0
PR 2249
The specification now describes in more detail how to determine the effective encoding value.
PR 2256
In the interests of consistency, the index-of function now defines equality to mean contextually equal. This has the implication that NaN is now considered equal to NaN.
PR 2259
A new parameter canonical is available to give control over serialization of XML, XHTML, and JSON.
PR 2286
The type of $value has been generalized to xs:anyAtomicType?.
PR 2387
It is now recommended that out-of-range xs:double values should translate to positive or negative infinity.