From 53e90ef86eb84466586e3d5357fd6dc4212f0a98 Mon Sep 17 00:00:00 2001 From: alexandrev-tibco Date: Sun, 19 Apr 2026 09:28:05 +0200 Subject: [PATCH] =?UTF-8?q?feat(blog):=20complete=20XSLT/XPath=20reference?= =?UTF-8?q?=20=E2=80=94=20229=20function=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Full coverage of XSLT 1.0, 2.0 and 3.0 elements and XPath functions: - 59 XSLT elements (xsl:stylesheet → xsl:use-accumulators) - 170 XPath functions (1.0 node/string/numeric/boolean, 2.0 sequence/ date/QName/string, 3.0 HOF/map/array/JSON/streaming) Each page: description, parameters table, return value, 2 runnable Saxon examples with input XML + stylesheet + output, notes, cross-links. xsltCompletions.js: all 229 entries now have blogSlug for hover links. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/lib/xsltCompletions.js | 422 +++++++++--------- site/content/xslt/functions/xpath-abs.md | 107 +++++ .../xslt/functions/xpath-accumulator-after.md | 116 +++++ .../functions/xpath-accumulator-before.md | 119 +++++ site/content/xslt/functions/xpath-apply.md | 118 +++++ .../xslt/functions/xpath-array-append.md | 119 +++++ .../xslt/functions/xpath-array-filter.md | 131 ++++++ .../xslt/functions/xpath-array-flatten.md | 128 ++++++ .../xslt/functions/xpath-array-fold-left.md | 127 ++++++ .../xslt/functions/xpath-array-fold-right.md | 127 ++++++ .../functions/xpath-array-for-each-pair.md | 115 +++++ .../xslt/functions/xpath-array-for-each.md | 115 +++++ .../content/xslt/functions/xpath-array-get.md | 110 +++++ .../xslt/functions/xpath-array-head.md | 104 +++++ .../functions/xpath-array-insert-before.md | 108 +++++ .../xslt/functions/xpath-array-join.md | 121 +++++ .../content/xslt/functions/xpath-array-put.md | 115 +++++ .../xslt/functions/xpath-array-remove.md | 104 +++++ .../xslt/functions/xpath-array-reverse.md | 121 +++++ .../xslt/functions/xpath-array-size.md | 107 +++++ .../xslt/functions/xpath-array-sort.md | 112 +++++ .../xslt/functions/xpath-array-subarray.md | 115 +++++ .../xslt/functions/xpath-array-tail.md | 110 +++++ .../xpath-available-environment-variables.md | 92 ++++ site/content/xslt/functions/xpath-avg.md | 118 +++++ site/content/xslt/functions/xpath-base-uri.md | 100 +++++ site/content/xslt/functions/xpath-boolean.md | 116 +++++ site/content/xslt/functions/xpath-ceiling.md | 121 +++++ .../functions/xpath-codepoints-to-string.md | 120 +++++ .../xslt/functions/xpath-collection.md | 94 ++++ site/content/xslt/functions/xpath-compare.md | 130 ++++++ site/content/xslt/functions/xpath-copy-of.md | 110 +++++ .../xslt/functions/xpath-current-date-time.md | 94 ++++ .../xslt/functions/xpath-current-date.md | 96 ++++ .../xslt/functions/xpath-current-group.md | 102 +++++ .../functions/xpath-current-grouping-key.md | 110 +++++ .../functions/xpath-current-merge-group.md | 117 +++++ .../xslt/functions/xpath-current-merge-key.md | 123 +++++ .../functions/xpath-current-output-uri.md | 97 ++++ .../xslt/functions/xpath-current-time.md | 94 ++++ .../xslt/functions/xpath-day-from-date.md | 105 +++++ .../xslt/functions/xpath-deep-equal.md | 107 +++++ .../xslt/functions/xpath-distinct-values.md | 130 ++++++ .../xslt/functions/xpath-document-uri.md | 86 ++++ site/content/xslt/functions/xpath-document.md | 126 ++++++ .../xslt/functions/xpath-element-available.md | 106 +++++ site/content/xslt/functions/xpath-empty.md | 107 +++++ .../content/xslt/functions/xpath-ends-with.md | 102 +++++ .../functions/xpath-environment-variable.md | 99 ++++ site/content/xslt/functions/xpath-error.md | 109 +++++ .../xslt/functions/xpath-exactly-one.md | 109 +++++ site/content/xslt/functions/xpath-exists.md | 110 +++++ site/content/xslt/functions/xpath-false.md | 124 +++++ site/content/xslt/functions/xpath-filter.md | 116 +++++ site/content/xslt/functions/xpath-floor.md | 121 +++++ .../content/xslt/functions/xpath-fold-left.md | 114 +++++ .../xslt/functions/xpath-fold-right.md | 105 +++++ .../xslt/functions/xpath-for-each-pair.md | 117 +++++ site/content/xslt/functions/xpath-for-each.md | 114 +++++ .../xslt/functions/xpath-format-date-time.md | 122 +++++ .../xslt/functions/xpath-format-number.md | 129 ++++++ .../xslt/functions/xpath-format-time.md | 114 +++++ .../xslt/functions/xpath-function-arity.md | 109 +++++ .../functions/xpath-function-available.md | 123 +++++ .../xslt/functions/xpath-function-lookup.md | 114 +++++ .../xslt/functions/xpath-function-name.md | 115 +++++ .../xslt/functions/xpath-generate-id.md | 136 ++++++ .../xslt/functions/xpath-has-children.md | 105 +++++ .../xslt/functions/xpath-hours-from-time.md | 100 +++++ site/content/xslt/functions/xpath-id.md | 109 +++++ .../xslt/functions/xpath-implicit-timezone.md | 86 ++++ site/content/xslt/functions/xpath-index-of.md | 116 +++++ .../content/xslt/functions/xpath-innermost.md | 110 +++++ .../xslt/functions/xpath-insert-before.md | 115 +++++ site/content/xslt/functions/xpath-json-doc.md | 112 +++++ .../xslt/functions/xpath-json-to-xml.md | 128 ++++++ site/content/xslt/functions/xpath-lang.md | 116 +++++ .../functions/xpath-local-name-from-qname.md | 102 +++++ .../xslt/functions/xpath-local-name.md | 121 +++++ .../xslt/functions/xpath-lower-case.md | 117 +++++ .../xslt/functions/xpath-map-contains.md | 115 +++++ .../content/xslt/functions/xpath-map-entry.md | 120 +++++ site/content/xslt/functions/xpath-map-get.md | 115 +++++ site/content/xslt/functions/xpath-map-keys.md | 112 +++++ .../content/xslt/functions/xpath-map-merge.md | 111 +++++ site/content/xslt/functions/xpath-map-put.md | 119 +++++ .../xslt/functions/xpath-map-remove.md | 114 +++++ site/content/xslt/functions/xpath-map-size.md | 113 +++++ site/content/xslt/functions/xpath-max.md | 111 +++++ site/content/xslt/functions/xpath-min.md | 111 +++++ .../xslt/functions/xpath-minutes-from-time.md | 98 ++++ .../xslt/functions/xpath-month-from-date.md | 103 +++++ site/content/xslt/functions/xpath-name.md | 123 +++++ .../xpath-namespace-uri-from-qname.md | 101 +++++ .../xslt/functions/xpath-namespace-uri.md | 120 +++++ site/content/xslt/functions/xpath-nilled.md | 96 ++++ .../content/xslt/functions/xpath-node-name.md | 103 +++++ .../xslt/functions/xpath-normalize-space.md | 121 +++++ .../xslt/functions/xpath-normalize-unicode.md | 104 +++++ site/content/xslt/functions/xpath-not.md | 117 +++++ site/content/xslt/functions/xpath-number.md | 127 ++++++ .../xslt/functions/xpath-one-or-more.md | 108 +++++ .../content/xslt/functions/xpath-outermost.md | 104 +++++ .../xslt/functions/xpath-parse-json.md | 115 +++++ .../functions/xpath-parse-xml-fragment.md | 97 ++++ .../content/xslt/functions/xpath-parse-xml.md | 97 ++++ site/content/xslt/functions/xpath-path.md | 103 +++++ .../xslt/functions/xpath-prefix-from-qname.md | 100 +++++ site/content/xslt/functions/xpath-qname.md | 97 ++++ .../xpath-random-number-generator.md | 112 +++++ .../xslt/functions/xpath-regex-group.md | 125 ++++++ site/content/xslt/functions/xpath-remove.md | 108 +++++ .../xslt/functions/xpath-resolve-qname.md | 107 +++++ site/content/xslt/functions/xpath-reverse.md | 111 +++++ site/content/xslt/functions/xpath-round.md | 119 +++++ .../xslt/functions/xpath-seconds-from-time.md | 100 +++++ .../content/xslt/functions/xpath-serialize.md | 125 ++++++ site/content/xslt/functions/xpath-snapshot.md | 113 +++++ site/content/xslt/functions/xpath-sort.md | 113 +++++ .../xslt/functions/xpath-starts-with.md | 119 +++++ .../xslt/functions/xpath-static-base-uri.md | 87 ++++ .../xslt/functions/xpath-string-length.md | 116 +++++ .../functions/xpath-string-to-codepoints.md | 111 +++++ site/content/xslt/functions/xpath-string.md | 120 +++++ .../xslt/functions/xpath-subsequence.md | 114 +++++ .../xslt/functions/xpath-substring-after.md | 117 +++++ .../xslt/functions/xpath-substring-before.md | 120 +++++ .../xslt/functions/xpath-system-property.md | 121 +++++ site/content/xslt/functions/xpath-trace.md | 114 +++++ .../content/xslt/functions/xpath-translate.md | 125 ++++++ site/content/xslt/functions/xpath-true.md | 125 ++++++ .../xslt/functions/xpath-type-available.md | 109 +++++ .../content/xslt/functions/xpath-unordered.md | 115 +++++ .../functions/xpath-unparsed-entity-uri.md | 125 ++++++ .../xpath-unparsed-text-available.md | 86 ++++ .../functions/xpath-unparsed-text-lines.md | 90 ++++ .../xslt/functions/xpath-unparsed-text.md | 87 ++++ .../xslt/functions/xpath-upper-case.md | 97 ++++ .../xslt/functions/xpath-uri-collection.md | 92 ++++ .../xslt/functions/xpath-xml-to-json.md | 142 ++++++ .../xslt/functions/xpath-year-from-date.md | 96 ++++ .../xslt/functions/xpath-zero-or-one.md | 110 +++++ site/content/xslt/functions/xsl-accept.md | 111 +++++ .../xslt/functions/xsl-accumulator-rule.md | 124 +++++ .../content/xslt/functions/xsl-accumulator.md | 133 ++++++ .../xslt/functions/xsl-analyze-string.md | 139 ++++++ .../xslt/functions/xsl-apply-templates.md | 151 +++++++ .../xslt/functions/xsl-array-member.md | 113 +++++ site/content/xslt/functions/xsl-array.md | 115 +++++ .../xslt/functions/xsl-attribute-set.md | 140 ++++++ site/content/xslt/functions/xsl-attribute.md | 117 +++++ site/content/xslt/functions/xsl-break.md | 124 +++++ .../xslt/functions/xsl-call-template.md | 131 ++++++ site/content/xslt/functions/xsl-catch.md | 134 ++++++ .../xslt/functions/xsl-character-map.md | 115 +++++ site/content/xslt/functions/xsl-choose.md | 134 ++++++ site/content/xslt/functions/xsl-comment.md | 104 +++++ site/content/xslt/functions/xsl-copy-of.md | 124 +++++ site/content/xslt/functions/xsl-copy.md | 122 +++++ .../xslt/functions/xsl-decimal-format.md | 127 ++++++ site/content/xslt/functions/xsl-element.md | 122 +++++ site/content/xslt/functions/xsl-expose.md | 134 ++++++ site/content/xslt/functions/xsl-fallback.md | 92 ++++ site/content/xslt/functions/xsl-fork.md | 105 +++++ site/content/xslt/functions/xsl-if.md | 118 +++++ .../xslt/functions/xsl-import-schema.md | 120 +++++ site/content/xslt/functions/xsl-import.md | 129 ++++++ site/content/xslt/functions/xsl-include.md | 120 +++++ site/content/xslt/functions/xsl-key.md | 135 ++++++ site/content/xslt/functions/xsl-map-entry.md | 112 +++++ site/content/xslt/functions/xsl-map.md | 106 +++++ .../xslt/functions/xsl-matching-substring.md | 117 +++++ .../xslt/functions/xsl-merge-action.md | 106 +++++ site/content/xslt/functions/xsl-merge-key.md | 107 +++++ .../xslt/functions/xsl-merge-source.md | 106 +++++ site/content/xslt/functions/xsl-merge.md | 123 +++++ site/content/xslt/functions/xsl-message.md | 119 +++++ site/content/xslt/functions/xsl-mode.md | 128 ++++++ .../xslt/functions/xsl-namespace-alias.md | 123 +++++ site/content/xslt/functions/xsl-namespace.md | 106 +++++ .../xslt/functions/xsl-next-iteration.md | 115 +++++ site/content/xslt/functions/xsl-next-match.md | 111 +++++ .../functions/xsl-non-matching-substring.md | 110 +++++ site/content/xslt/functions/xsl-number.md | 130 ++++++ site/content/xslt/functions/xsl-on-empty.md | 105 +++++ .../xslt/functions/xsl-on-non-empty.md | 110 +++++ site/content/xslt/functions/xsl-otherwise.md | 124 +++++ .../xslt/functions/xsl-output-character.md | 93 ++++ site/content/xslt/functions/xsl-output.md | 117 +++++ site/content/xslt/functions/xsl-override.md | 137 ++++++ site/content/xslt/functions/xsl-package.md | 103 +++++ site/content/xslt/functions/xsl-param.md | 116 +++++ .../xslt/functions/xsl-perform-sort.md | 116 +++++ .../xslt/functions/xsl-preserve-space.md | 113 +++++ .../functions/xsl-processing-instruction.md | 114 +++++ .../xslt/functions/xsl-result-document.md | 127 ++++++ site/content/xslt/functions/xsl-sequence.md | 121 +++++ site/content/xslt/functions/xsl-sort.md | 127 ++++++ site/content/xslt/functions/xsl-stream.md | 101 +++++ .../content/xslt/functions/xsl-strip-space.md | 133 ++++++ site/content/xslt/functions/xsl-stylesheet.md | 108 +++++ site/content/xslt/functions/xsl-template.md | 124 +++++ site/content/xslt/functions/xsl-text.md | 105 +++++ site/content/xslt/functions/xsl-transform.md | 92 ++++ site/content/xslt/functions/xsl-try.md | 111 +++++ .../xslt/functions/xsl-use-accumulators.md | 142 ++++++ .../content/xslt/functions/xsl-use-package.md | 117 +++++ site/content/xslt/functions/xsl-variable.md | 116 +++++ site/content/xslt/functions/xsl-when.md | 133 ++++++ .../xslt/functions/xsl-where-populated.md | 113 +++++ site/content/xslt/functions/xsl-with-param.md | 127 ++++++ 211 files changed, 24143 insertions(+), 211 deletions(-) create mode 100644 site/content/xslt/functions/xpath-abs.md create mode 100644 site/content/xslt/functions/xpath-accumulator-after.md create mode 100644 site/content/xslt/functions/xpath-accumulator-before.md create mode 100644 site/content/xslt/functions/xpath-apply.md create mode 100644 site/content/xslt/functions/xpath-array-append.md create mode 100644 site/content/xslt/functions/xpath-array-filter.md create mode 100644 site/content/xslt/functions/xpath-array-flatten.md create mode 100644 site/content/xslt/functions/xpath-array-fold-left.md create mode 100644 site/content/xslt/functions/xpath-array-fold-right.md create mode 100644 site/content/xslt/functions/xpath-array-for-each-pair.md create mode 100644 site/content/xslt/functions/xpath-array-for-each.md create mode 100644 site/content/xslt/functions/xpath-array-get.md create mode 100644 site/content/xslt/functions/xpath-array-head.md create mode 100644 site/content/xslt/functions/xpath-array-insert-before.md create mode 100644 site/content/xslt/functions/xpath-array-join.md create mode 100644 site/content/xslt/functions/xpath-array-put.md create mode 100644 site/content/xslt/functions/xpath-array-remove.md create mode 100644 site/content/xslt/functions/xpath-array-reverse.md create mode 100644 site/content/xslt/functions/xpath-array-size.md create mode 100644 site/content/xslt/functions/xpath-array-sort.md create mode 100644 site/content/xslt/functions/xpath-array-subarray.md create mode 100644 site/content/xslt/functions/xpath-array-tail.md create mode 100644 site/content/xslt/functions/xpath-available-environment-variables.md create mode 100644 site/content/xslt/functions/xpath-avg.md create mode 100644 site/content/xslt/functions/xpath-base-uri.md create mode 100644 site/content/xslt/functions/xpath-boolean.md create mode 100644 site/content/xslt/functions/xpath-ceiling.md create mode 100644 site/content/xslt/functions/xpath-codepoints-to-string.md create mode 100644 site/content/xslt/functions/xpath-collection.md create mode 100644 site/content/xslt/functions/xpath-compare.md create mode 100644 site/content/xslt/functions/xpath-copy-of.md create mode 100644 site/content/xslt/functions/xpath-current-date-time.md create mode 100644 site/content/xslt/functions/xpath-current-date.md create mode 100644 site/content/xslt/functions/xpath-current-group.md create mode 100644 site/content/xslt/functions/xpath-current-grouping-key.md create mode 100644 site/content/xslt/functions/xpath-current-merge-group.md create mode 100644 site/content/xslt/functions/xpath-current-merge-key.md create mode 100644 site/content/xslt/functions/xpath-current-output-uri.md create mode 100644 site/content/xslt/functions/xpath-current-time.md create mode 100644 site/content/xslt/functions/xpath-day-from-date.md create mode 100644 site/content/xslt/functions/xpath-deep-equal.md create mode 100644 site/content/xslt/functions/xpath-distinct-values.md create mode 100644 site/content/xslt/functions/xpath-document-uri.md create mode 100644 site/content/xslt/functions/xpath-document.md create mode 100644 site/content/xslt/functions/xpath-element-available.md create mode 100644 site/content/xslt/functions/xpath-empty.md create mode 100644 site/content/xslt/functions/xpath-ends-with.md create mode 100644 site/content/xslt/functions/xpath-environment-variable.md create mode 100644 site/content/xslt/functions/xpath-error.md create mode 100644 site/content/xslt/functions/xpath-exactly-one.md create mode 100644 site/content/xslt/functions/xpath-exists.md create mode 100644 site/content/xslt/functions/xpath-false.md create mode 100644 site/content/xslt/functions/xpath-filter.md create mode 100644 site/content/xslt/functions/xpath-floor.md create mode 100644 site/content/xslt/functions/xpath-fold-left.md create mode 100644 site/content/xslt/functions/xpath-fold-right.md create mode 100644 site/content/xslt/functions/xpath-for-each-pair.md create mode 100644 site/content/xslt/functions/xpath-for-each.md create mode 100644 site/content/xslt/functions/xpath-format-date-time.md create mode 100644 site/content/xslt/functions/xpath-format-number.md create mode 100644 site/content/xslt/functions/xpath-format-time.md create mode 100644 site/content/xslt/functions/xpath-function-arity.md create mode 100644 site/content/xslt/functions/xpath-function-available.md create mode 100644 site/content/xslt/functions/xpath-function-lookup.md create mode 100644 site/content/xslt/functions/xpath-function-name.md create mode 100644 site/content/xslt/functions/xpath-generate-id.md create mode 100644 site/content/xslt/functions/xpath-has-children.md create mode 100644 site/content/xslt/functions/xpath-hours-from-time.md create mode 100644 site/content/xslt/functions/xpath-id.md create mode 100644 site/content/xslt/functions/xpath-implicit-timezone.md create mode 100644 site/content/xslt/functions/xpath-index-of.md create mode 100644 site/content/xslt/functions/xpath-innermost.md create mode 100644 site/content/xslt/functions/xpath-insert-before.md create mode 100644 site/content/xslt/functions/xpath-json-doc.md create mode 100644 site/content/xslt/functions/xpath-json-to-xml.md create mode 100644 site/content/xslt/functions/xpath-lang.md create mode 100644 site/content/xslt/functions/xpath-local-name-from-qname.md create mode 100644 site/content/xslt/functions/xpath-local-name.md create mode 100644 site/content/xslt/functions/xpath-lower-case.md create mode 100644 site/content/xslt/functions/xpath-map-contains.md create mode 100644 site/content/xslt/functions/xpath-map-entry.md create mode 100644 site/content/xslt/functions/xpath-map-get.md create mode 100644 site/content/xslt/functions/xpath-map-keys.md create mode 100644 site/content/xslt/functions/xpath-map-merge.md create mode 100644 site/content/xslt/functions/xpath-map-put.md create mode 100644 site/content/xslt/functions/xpath-map-remove.md create mode 100644 site/content/xslt/functions/xpath-map-size.md create mode 100644 site/content/xslt/functions/xpath-max.md create mode 100644 site/content/xslt/functions/xpath-min.md create mode 100644 site/content/xslt/functions/xpath-minutes-from-time.md create mode 100644 site/content/xslt/functions/xpath-month-from-date.md create mode 100644 site/content/xslt/functions/xpath-name.md create mode 100644 site/content/xslt/functions/xpath-namespace-uri-from-qname.md create mode 100644 site/content/xslt/functions/xpath-namespace-uri.md create mode 100644 site/content/xslt/functions/xpath-nilled.md create mode 100644 site/content/xslt/functions/xpath-node-name.md create mode 100644 site/content/xslt/functions/xpath-normalize-space.md create mode 100644 site/content/xslt/functions/xpath-normalize-unicode.md create mode 100644 site/content/xslt/functions/xpath-not.md create mode 100644 site/content/xslt/functions/xpath-number.md create mode 100644 site/content/xslt/functions/xpath-one-or-more.md create mode 100644 site/content/xslt/functions/xpath-outermost.md create mode 100644 site/content/xslt/functions/xpath-parse-json.md create mode 100644 site/content/xslt/functions/xpath-parse-xml-fragment.md create mode 100644 site/content/xslt/functions/xpath-parse-xml.md create mode 100644 site/content/xslt/functions/xpath-path.md create mode 100644 site/content/xslt/functions/xpath-prefix-from-qname.md create mode 100644 site/content/xslt/functions/xpath-qname.md create mode 100644 site/content/xslt/functions/xpath-random-number-generator.md create mode 100644 site/content/xslt/functions/xpath-regex-group.md create mode 100644 site/content/xslt/functions/xpath-remove.md create mode 100644 site/content/xslt/functions/xpath-resolve-qname.md create mode 100644 site/content/xslt/functions/xpath-reverse.md create mode 100644 site/content/xslt/functions/xpath-round.md create mode 100644 site/content/xslt/functions/xpath-seconds-from-time.md create mode 100644 site/content/xslt/functions/xpath-serialize.md create mode 100644 site/content/xslt/functions/xpath-snapshot.md create mode 100644 site/content/xslt/functions/xpath-sort.md create mode 100644 site/content/xslt/functions/xpath-starts-with.md create mode 100644 site/content/xslt/functions/xpath-static-base-uri.md create mode 100644 site/content/xslt/functions/xpath-string-length.md create mode 100644 site/content/xslt/functions/xpath-string-to-codepoints.md create mode 100644 site/content/xslt/functions/xpath-string.md create mode 100644 site/content/xslt/functions/xpath-subsequence.md create mode 100644 site/content/xslt/functions/xpath-substring-after.md create mode 100644 site/content/xslt/functions/xpath-substring-before.md create mode 100644 site/content/xslt/functions/xpath-system-property.md create mode 100644 site/content/xslt/functions/xpath-trace.md create mode 100644 site/content/xslt/functions/xpath-translate.md create mode 100644 site/content/xslt/functions/xpath-true.md create mode 100644 site/content/xslt/functions/xpath-type-available.md create mode 100644 site/content/xslt/functions/xpath-unordered.md create mode 100644 site/content/xslt/functions/xpath-unparsed-entity-uri.md create mode 100644 site/content/xslt/functions/xpath-unparsed-text-available.md create mode 100644 site/content/xslt/functions/xpath-unparsed-text-lines.md create mode 100644 site/content/xslt/functions/xpath-unparsed-text.md create mode 100644 site/content/xslt/functions/xpath-upper-case.md create mode 100644 site/content/xslt/functions/xpath-uri-collection.md create mode 100644 site/content/xslt/functions/xpath-xml-to-json.md create mode 100644 site/content/xslt/functions/xpath-year-from-date.md create mode 100644 site/content/xslt/functions/xpath-zero-or-one.md create mode 100644 site/content/xslt/functions/xsl-accept.md create mode 100644 site/content/xslt/functions/xsl-accumulator-rule.md create mode 100644 site/content/xslt/functions/xsl-accumulator.md create mode 100644 site/content/xslt/functions/xsl-analyze-string.md create mode 100644 site/content/xslt/functions/xsl-apply-templates.md create mode 100644 site/content/xslt/functions/xsl-array-member.md create mode 100644 site/content/xslt/functions/xsl-array.md create mode 100644 site/content/xslt/functions/xsl-attribute-set.md create mode 100644 site/content/xslt/functions/xsl-attribute.md create mode 100644 site/content/xslt/functions/xsl-break.md create mode 100644 site/content/xslt/functions/xsl-call-template.md create mode 100644 site/content/xslt/functions/xsl-catch.md create mode 100644 site/content/xslt/functions/xsl-character-map.md create mode 100644 site/content/xslt/functions/xsl-choose.md create mode 100644 site/content/xslt/functions/xsl-comment.md create mode 100644 site/content/xslt/functions/xsl-copy-of.md create mode 100644 site/content/xslt/functions/xsl-copy.md create mode 100644 site/content/xslt/functions/xsl-decimal-format.md create mode 100644 site/content/xslt/functions/xsl-element.md create mode 100644 site/content/xslt/functions/xsl-expose.md create mode 100644 site/content/xslt/functions/xsl-fallback.md create mode 100644 site/content/xslt/functions/xsl-fork.md create mode 100644 site/content/xslt/functions/xsl-if.md create mode 100644 site/content/xslt/functions/xsl-import-schema.md create mode 100644 site/content/xslt/functions/xsl-import.md create mode 100644 site/content/xslt/functions/xsl-include.md create mode 100644 site/content/xslt/functions/xsl-key.md create mode 100644 site/content/xslt/functions/xsl-map-entry.md create mode 100644 site/content/xslt/functions/xsl-map.md create mode 100644 site/content/xslt/functions/xsl-matching-substring.md create mode 100644 site/content/xslt/functions/xsl-merge-action.md create mode 100644 site/content/xslt/functions/xsl-merge-key.md create mode 100644 site/content/xslt/functions/xsl-merge-source.md create mode 100644 site/content/xslt/functions/xsl-merge.md create mode 100644 site/content/xslt/functions/xsl-message.md create mode 100644 site/content/xslt/functions/xsl-mode.md create mode 100644 site/content/xslt/functions/xsl-namespace-alias.md create mode 100644 site/content/xslt/functions/xsl-namespace.md create mode 100644 site/content/xslt/functions/xsl-next-iteration.md create mode 100644 site/content/xslt/functions/xsl-next-match.md create mode 100644 site/content/xslt/functions/xsl-non-matching-substring.md create mode 100644 site/content/xslt/functions/xsl-number.md create mode 100644 site/content/xslt/functions/xsl-on-empty.md create mode 100644 site/content/xslt/functions/xsl-on-non-empty.md create mode 100644 site/content/xslt/functions/xsl-otherwise.md create mode 100644 site/content/xslt/functions/xsl-output-character.md create mode 100644 site/content/xslt/functions/xsl-output.md create mode 100644 site/content/xslt/functions/xsl-override.md create mode 100644 site/content/xslt/functions/xsl-package.md create mode 100644 site/content/xslt/functions/xsl-param.md create mode 100644 site/content/xslt/functions/xsl-perform-sort.md create mode 100644 site/content/xslt/functions/xsl-preserve-space.md create mode 100644 site/content/xslt/functions/xsl-processing-instruction.md create mode 100644 site/content/xslt/functions/xsl-result-document.md create mode 100644 site/content/xslt/functions/xsl-sequence.md create mode 100644 site/content/xslt/functions/xsl-sort.md create mode 100644 site/content/xslt/functions/xsl-stream.md create mode 100644 site/content/xslt/functions/xsl-strip-space.md create mode 100644 site/content/xslt/functions/xsl-stylesheet.md create mode 100644 site/content/xslt/functions/xsl-template.md create mode 100644 site/content/xslt/functions/xsl-text.md create mode 100644 site/content/xslt/functions/xsl-transform.md create mode 100644 site/content/xslt/functions/xsl-try.md create mode 100644 site/content/xslt/functions/xsl-use-accumulators.md create mode 100644 site/content/xslt/functions/xsl-use-package.md create mode 100644 site/content/xslt/functions/xsl-variable.md create mode 100644 site/content/xslt/functions/xsl-when.md create mode 100644 site/content/xslt/functions/xsl-where-populated.md create mode 100644 site/content/xslt/functions/xsl-with-param.md diff --git a/frontend/src/lib/xsltCompletions.js b/frontend/src/lib/xsltCompletions.js index 27c53c4d..5263bd37 100644 --- a/frontend/src/lib/xsltCompletions.js +++ b/frontend/src/lib/xsltCompletions.js @@ -9,83 +9,83 @@ export const XSL_ELEMENTS = [ // 1.0 - { label: "xsl:stylesheet", minVersion: "1.0", info: "Root element of an XSLT stylesheet", args: 'version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"' }, - { label: "xsl:transform", minVersion: "1.0", info: "Synonym for xsl:stylesheet", args: 'version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"' }, - { label: "xsl:template", minVersion: "1.0", info: "Defines a reusable template rule", args: 'match="/"' }, - { label: "xsl:apply-templates", minVersion: "1.0", info: "Applies templates to child nodes", args: 'select="node()"' }, - { label: "xsl:call-template", minVersion: "1.0", info: "Calls a named template", args: 'name="templateName"' }, + { label: "xsl:stylesheet", minVersion: "1.0", info: "Root element of an XSLT stylesheet", args: 'version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"', blogSlug: "xsl-stylesheet" }, + { label: "xsl:transform", minVersion: "1.0", info: "Synonym for xsl:stylesheet", args: 'version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"', blogSlug: "xsl-transform" }, + { label: "xsl:template", minVersion: "1.0", info: "Defines a reusable template rule", args: 'match="/"', blogSlug: "xsl-template" }, + { label: "xsl:apply-templates", minVersion: "1.0", info: "Applies templates to child nodes", args: 'select="node()"', blogSlug: "xsl-apply-templates" }, + { label: "xsl:call-template", minVersion: "1.0", info: "Calls a named template", args: 'name="templateName"', blogSlug: "xsl-call-template" }, { label: "xsl:value-of", minVersion: "1.0", info: "Outputs the string value of an XPath expression", args: 'select="."', blogSlug: "xsl-value-of" }, { label: "xsl:for-each", minVersion: "1.0", info: "Iterates over a node-set", args: 'select="items/item"', blogSlug: "xsl-for-each" }, - { label: "xsl:if", minVersion: "1.0", info: "Conditional output", args: 'test="condition"' }, - { label: "xsl:choose", minVersion: "1.0", info: "Switch-like conditional block (use with xsl:when / xsl:otherwise)" }, - { label: "xsl:when", minVersion: "1.0", info: "Condition branch inside xsl:choose", args: 'test="condition"' }, - { label: "xsl:otherwise", minVersion: "1.0", info: "Default branch inside xsl:choose" }, - { label: "xsl:variable", minVersion: "1.0", info: "Declares a variable", args: 'name="varName" select="."' }, - { label: "xsl:param", minVersion: "1.0", info: "Declares a parameter (template or stylesheet level)", args: 'name="paramName"' }, - { label: "xsl:with-param", minVersion: "1.0", info: "Passes a parameter to a template", args: 'name="paramName" select="."' }, - { label: "xsl:sort", minVersion: "1.0", info: "Sorts nodes inside xsl:for-each or xsl:apply-templates", args: 'select="." order="ascending"' }, - { label: "xsl:copy", minVersion: "1.0", info: "Shallow-copies the current node" }, - { label: "xsl:copy-of", minVersion: "1.0", info: "Deep-copies a node-set or value", args: 'select="."' }, - { label: "xsl:text", minVersion: "1.0", info: "Outputs literal text (preserves whitespace)" }, - { label: "xsl:element", minVersion: "1.0", info: "Creates an element with a computed name", args: 'name="elementName"' }, - { label: "xsl:attribute", minVersion: "1.0", info: "Creates an attribute on the parent element", args: 'name="attrName"' }, - { label: "xsl:attribute-set", minVersion: "1.0", info: "Defines a named set of attributes", args: 'name="setName"' }, - { label: "xsl:comment", minVersion: "1.0", info: "Outputs an XML comment" }, - { label: "xsl:processing-instruction", minVersion: "1.0", info: "Outputs a processing instruction", args: 'name="piName"' }, - { label: "xsl:include", minVersion: "1.0", info: "Includes another stylesheet", args: 'href="other.xsl"' }, - { label: "xsl:import", minVersion: "1.0", info: "Imports another stylesheet (lower precedence)", args: 'href="other.xsl"' }, - { label: "xsl:output", minVersion: "1.0", info: "Controls serialization of the result tree", args: 'method="xml" indent="yes"' }, - { label: "xsl:preserve-space", minVersion: "1.0", info: "Preserves whitespace in specified elements", args: 'elements="*"' }, - { label: "xsl:strip-space", minVersion: "1.0", info: "Strips whitespace from specified elements", args: 'elements="*"' }, - { label: "xsl:key", minVersion: "1.0", info: "Defines an index key for the key() function", args: 'name="keyName" match="element" use="@id"' }, - { label: "xsl:decimal-format", minVersion: "1.0", info: "Defines a decimal format for format-number()" }, - { label: "xsl:namespace-alias", minVersion: "1.0", info: "Maps a namespace prefix to another", args: 'stylesheet-prefix="xsl" result-prefix="out"' }, - { label: "xsl:number", minVersion: "1.0", info: "Formats a number or generates a sequence number", args: 'value="position()"' }, - { label: "xsl:message", minVersion: "1.0", info: "Emits a diagnostic message (may terminate)", args: 'terminate="no"' }, - { label: "xsl:fallback", minVersion: "1.0", info: "Fallback content for unrecognized extension elements" }, + { label: "xsl:if", minVersion: "1.0", info: "Conditional output", args: 'test="condition"', blogSlug: "xsl-if" }, + { label: "xsl:choose", minVersion: "1.0", info: "Switch-like conditional block (use with xsl:when / xsl:otherwise)", blogSlug: "xsl-choose" }, + { label: "xsl:when", minVersion: "1.0", info: "Condition branch inside xsl:choose", args: 'test="condition"', blogSlug: "xsl-when" }, + { label: "xsl:otherwise", minVersion: "1.0", info: "Default branch inside xsl:choose", blogSlug: "xsl-otherwise" }, + { label: "xsl:variable", minVersion: "1.0", info: "Declares a variable", args: 'name="varName" select="."', blogSlug: "xsl-variable" }, + { label: "xsl:param", minVersion: "1.0", info: "Declares a parameter (template or stylesheet level)", args: 'name="paramName"', blogSlug: "xsl-param" }, + { label: "xsl:with-param", minVersion: "1.0", info: "Passes a parameter to a template", args: 'name="paramName" select="."', blogSlug: "xsl-with-param" }, + { label: "xsl:sort", minVersion: "1.0", info: "Sorts nodes inside xsl:for-each or xsl:apply-templates", args: 'select="." order="ascending"', blogSlug: "xsl-sort" }, + { label: "xsl:copy", minVersion: "1.0", info: "Shallow-copies the current node", blogSlug: "xsl-copy" }, + { label: "xsl:copy-of", minVersion: "1.0", info: "Deep-copies a node-set or value", args: 'select="."', blogSlug: "xsl-copy-of" }, + { label: "xsl:text", minVersion: "1.0", info: "Outputs literal text (preserves whitespace)", blogSlug: "xsl-text" }, + { label: "xsl:element", minVersion: "1.0", info: "Creates an element with a computed name", args: 'name="elementName"', blogSlug: "xsl-element" }, + { label: "xsl:attribute", minVersion: "1.0", info: "Creates an attribute on the parent element", args: 'name="attrName"', blogSlug: "xsl-attribute" }, + { label: "xsl:attribute-set", minVersion: "1.0", info: "Defines a named set of attributes", args: 'name="setName"', blogSlug: "xsl-attribute-set" }, + { label: "xsl:comment", minVersion: "1.0", info: "Outputs an XML comment", blogSlug: "xsl-comment" }, + { label: "xsl:processing-instruction", minVersion: "1.0", info: "Outputs a processing instruction", args: 'name="piName"', blogSlug: "xsl-processing-instruction" }, + { label: "xsl:include", minVersion: "1.0", info: "Includes another stylesheet", args: 'href="other.xsl"', blogSlug: "xsl-include" }, + { label: "xsl:import", minVersion: "1.0", info: "Imports another stylesheet (lower precedence)", args: 'href="other.xsl"', blogSlug: "xsl-import" }, + { label: "xsl:output", minVersion: "1.0", info: "Controls serialization of the result tree", args: 'method="xml" indent="yes"', blogSlug: "xsl-output" }, + { label: "xsl:preserve-space", minVersion: "1.0", info: "Preserves whitespace in specified elements", args: 'elements="*"', blogSlug: "xsl-preserve-space" }, + { label: "xsl:strip-space", minVersion: "1.0", info: "Strips whitespace from specified elements", args: 'elements="*"', blogSlug: "xsl-strip-space" }, + { label: "xsl:key", minVersion: "1.0", info: "Defines an index key for the key() function", args: 'name="keyName" match="element" use="@id"', blogSlug: "xsl-key" }, + { label: "xsl:decimal-format", minVersion: "1.0", info: "Defines a decimal format for format-number()", blogSlug: "xsl-decimal-format" }, + { label: "xsl:namespace-alias", minVersion: "1.0", info: "Maps a namespace prefix to another", args: 'stylesheet-prefix="xsl" result-prefix="out"', blogSlug: "xsl-namespace-alias" }, + { label: "xsl:number", minVersion: "1.0", info: "Formats a number or generates a sequence number", args: 'value="position()"', blogSlug: "xsl-number" }, + { label: "xsl:message", minVersion: "1.0", info: "Emits a diagnostic message (may terminate)", args: 'terminate="no"', blogSlug: "xsl-message" }, + { label: "xsl:fallback", minVersion: "1.0", info: "Fallback content for unrecognized extension elements", blogSlug: "xsl-fallback" }, // 2.0 { label: "xsl:function", minVersion: "2.0", info: "Defines a stylesheet function callable from XPath", args: 'name="my:func" as="xs:string"', blogSlug: "xsl-function" }, - { label: "xsl:sequence", minVersion: "2.0", info: "Returns a sequence of items", args: 'select="()"' }, - { label: "xsl:next-match", minVersion: "2.0", info: "Applies the next-matching template rule" }, - { label: "xsl:perform-sort", minVersion: "2.0", info: "Sorts a sequence without iteration", args: 'select="items"' }, + { label: "xsl:sequence", minVersion: "2.0", info: "Returns a sequence of items", args: 'select="()"', blogSlug: "xsl-sequence" }, + { label: "xsl:next-match", minVersion: "2.0", info: "Applies the next-matching template rule", blogSlug: "xsl-next-match" }, + { label: "xsl:perform-sort", minVersion: "2.0", info: "Sorts a sequence without iteration", args: 'select="items"', blogSlug: "xsl-perform-sort" }, { label: "xsl:for-each-group", minVersion: "2.0", info: "Groups items in a sequence", args: 'select="items" group-by="."', blogSlug: "xsl-for-each-group" }, - { label: "xsl:analyze-string", minVersion: "2.0", info: "Processes a string against a regex", args: 'select="." regex="pattern"' }, - { label: "xsl:matching-substring", minVersion: "2.0", info: "Content within xsl:analyze-string for matching parts" }, - { label: "xsl:non-matching-substring", minVersion: "2.0", info: "Content within xsl:analyze-string for non-matching parts" }, - { label: "xsl:namespace", minVersion: "2.0", info: "Creates a namespace node", args: 'name="prefix"' }, - { label: "xsl:character-map", minVersion: "2.0", info: "Maps characters to strings during serialization", args: 'name="mapName"' }, - { label: "xsl:output-character", minVersion: "2.0", info: "Maps a single character inside xsl:character-map", args: 'character="&" string="&"' }, - { label: "xsl:import-schema", minVersion: "2.0", info: "Imports an XML Schema for type-aware processing", args: 'namespace="http://example.com"' }, - { label: "xsl:result-document", minVersion: "2.0", info: "Writes output to a secondary result document", args: 'href="output.xml" method="xml"' }, + { label: "xsl:analyze-string", minVersion: "2.0", info: "Processes a string against a regex", args: 'select="." regex="pattern"', blogSlug: "xsl-analyze-string" }, + { label: "xsl:matching-substring", minVersion: "2.0", info: "Content within xsl:analyze-string for matching parts", blogSlug: "xsl-matching-substring" }, + { label: "xsl:non-matching-substring", minVersion: "2.0", info: "Content within xsl:analyze-string for non-matching parts", blogSlug: "xsl-non-matching-substring" }, + { label: "xsl:namespace", minVersion: "2.0", info: "Creates a namespace node", args: 'name="prefix"', blogSlug: "xsl-namespace" }, + { label: "xsl:character-map", minVersion: "2.0", info: "Maps characters to strings during serialization", args: 'name="mapName"', blogSlug: "xsl-character-map" }, + { label: "xsl:output-character", minVersion: "2.0", info: "Maps a single character inside xsl:character-map", args: 'character="&" string="&"', blogSlug: "xsl-output-character" }, + { label: "xsl:import-schema", minVersion: "2.0", info: "Imports an XML Schema for type-aware processing", args: 'namespace="http://example.com"', blogSlug: "xsl-import-schema" }, + { label: "xsl:result-document", minVersion: "2.0", info: "Writes output to a secondary result document", args: 'href="output.xml" method="xml"', blogSlug: "xsl-result-document" }, // 3.0 - { label: "xsl:package", minVersion: "3.0", info: "Defines an XSLT 3.0 package", args: 'name="com.example.pkg" version="1.0"' }, - { label: "xsl:use-package", minVersion: "3.0", info: "Uses a compiled package", args: 'name="com.example.pkg"' }, - { label: "xsl:expose", minVersion: "3.0", info: "Controls visibility of components within a package", args: 'component="function" match="*" visibility="public"' }, - { label: "xsl:override", minVersion: "3.0", info: "Overrides components from a used package" }, - { label: "xsl:mode", minVersion: "3.0", info: "Declares a mode and its default behavior", args: 'name="modeName" on-no-match="shallow-copy"' }, - { label: "xsl:accept", minVersion: "3.0", info: "Accepts components from a used package", args: 'component="function" match="*" visibility="public"' }, - { label: "xsl:try", minVersion: "3.0", info: "Attempts an expression; catches errors", args: 'select="expression"' }, - { label: "xsl:catch", minVersion: "3.0", info: "Catches errors from xsl:try" }, - { label: "xsl:on-empty", minVersion: "3.0", info: "Content to output when the sequence is empty" }, - { label: "xsl:on-non-empty", minVersion: "3.0", info: "Content to output when the sequence is non-empty" }, - { label: "xsl:where-populated", minVersion: "3.0", info: "Suppresses output if the content would be empty" }, - { label: "xsl:map", minVersion: "3.0", info: "Creates an XPath 3.1 map", args: '' }, - { label: "xsl:map-entry", minVersion: "3.0", info: "Creates a key-value entry inside xsl:map", args: 'key="." select="."' }, - { label: "xsl:array", minVersion: "3.0", info: "Creates an XPath 3.1 array" }, - { label: "xsl:array-member", minVersion: "3.0", info: "Creates a member inside xsl:array", args: 'select="."' }, - { label: "xsl:stream", minVersion: "3.0", info: "Processes a document in streaming mode", args: 'href="large.xml"' }, + { label: "xsl:package", minVersion: "3.0", info: "Defines an XSLT 3.0 package", args: 'name="com.example.pkg" version="1.0"', blogSlug: "xsl-package" }, + { label: "xsl:use-package", minVersion: "3.0", info: "Uses a compiled package", args: 'name="com.example.pkg"', blogSlug: "xsl-use-package" }, + { label: "xsl:expose", minVersion: "3.0", info: "Controls visibility of components within a package", args: 'component="function" match="*" visibility="public"', blogSlug: "xsl-expose" }, + { label: "xsl:override", minVersion: "3.0", info: "Overrides components from a used package", blogSlug: "xsl-override" }, + { label: "xsl:mode", minVersion: "3.0", info: "Declares a mode and its default behavior", args: 'name="modeName" on-no-match="shallow-copy"', blogSlug: "xsl-mode" }, + { label: "xsl:accept", minVersion: "3.0", info: "Accepts components from a used package", args: 'component="function" match="*" visibility="public"', blogSlug: "xsl-accept" }, + { label: "xsl:try", minVersion: "3.0", info: "Attempts an expression; catches errors", args: 'select="expression"', blogSlug: "xsl-try" }, + { label: "xsl:catch", minVersion: "3.0", info: "Catches errors from xsl:try", blogSlug: "xsl-catch" }, + { label: "xsl:on-empty", minVersion: "3.0", info: "Content to output when the sequence is empty", blogSlug: "xsl-on-empty" }, + { label: "xsl:on-non-empty", minVersion: "3.0", info: "Content to output when the sequence is non-empty", blogSlug: "xsl-on-non-empty" }, + { label: "xsl:where-populated", minVersion: "3.0", info: "Suppresses output if the content would be empty", blogSlug: "xsl-where-populated" }, + { label: "xsl:map", minVersion: "3.0", info: "Creates an XPath 3.1 map", args: '', blogSlug: "xsl-map" }, + { label: "xsl:map-entry", minVersion: "3.0", info: "Creates a key-value entry inside xsl:map", args: 'key="." select="."', blogSlug: "xsl-map-entry" }, + { label: "xsl:array", minVersion: "3.0", info: "Creates an XPath 3.1 array", blogSlug: "xsl-array" }, + { label: "xsl:array-member", minVersion: "3.0", info: "Creates a member inside xsl:array", args: 'select="."', blogSlug: "xsl-array-member" }, + { label: "xsl:stream", minVersion: "3.0", info: "Processes a document in streaming mode", args: 'href="large.xml"', blogSlug: "xsl-stream" }, { label: "xsl:iterate", minVersion: "3.0", info: "Iterates with carry-over accumulators", args: 'select="items"', blogSlug: "xsl-iterate" }, { label: "xsl:param", minVersion: "3.0", info: "Streaming: parameter inside xsl:iterate" }, // duplicate intentional (context differs) - { label: "xsl:break", minVersion: "3.0", info: "Exits xsl:iterate early", args: 'select="."' }, - { label: "xsl:next-iteration", minVersion: "3.0", info: "Continues xsl:iterate with updated parameters" }, - { label: "xsl:fork", minVersion: "3.0", info: "Processes a sequence in multiple streams simultaneously" }, - { label: "xsl:merge", minVersion: "3.0", info: "Merges pre-sorted sequences", args: '' }, - { label: "xsl:merge-source", minVersion: "3.0", info: "Defines one source for xsl:merge", args: 'name="src" select="collection()"' }, - { label: "xsl:merge-key", minVersion: "3.0", info: "Defines the merge key inside xsl:merge-source", args: 'select="." order="ascending"' }, - { label: "xsl:merge-action", minVersion: "3.0", info: "Body executed for each group of merged items" }, - { label: "xsl:accumulator", minVersion: "3.0", info: "Defines a streaming accumulator", args: 'name="acc" initial-value="0"' }, - { label: "xsl:accumulator-rule", minVersion: "3.0", info: "Rule inside xsl:accumulator", args: 'match="element"' }, - { label: "xsl:use-accumulators", minVersion: "3.0", info: "Declares which accumulators are used in a template" }, + { label: "xsl:break", minVersion: "3.0", info: "Exits xsl:iterate early", args: 'select="."', blogSlug: "xsl-break" }, + { label: "xsl:next-iteration", minVersion: "3.0", info: "Continues xsl:iterate with updated parameters", blogSlug: "xsl-next-iteration" }, + { label: "xsl:fork", minVersion: "3.0", info: "Processes a sequence in multiple streams simultaneously", blogSlug: "xsl-fork" }, + { label: "xsl:merge", minVersion: "3.0", info: "Merges pre-sorted sequences", args: '', blogSlug: "xsl-merge" }, + { label: "xsl:merge-source", minVersion: "3.0", info: "Defines one source for xsl:merge", args: 'name="src" select="collection()"', blogSlug: "xsl-merge-source" }, + { label: "xsl:merge-key", minVersion: "3.0", info: "Defines the merge key inside xsl:merge-source", args: 'select="." order="ascending"', blogSlug: "xsl-merge-key" }, + { label: "xsl:merge-action", minVersion: "3.0", info: "Body executed for each group of merged items", blogSlug: "xsl-merge-action" }, + { label: "xsl:accumulator", minVersion: "3.0", info: "Defines a streaming accumulator", args: 'name="acc" initial-value="0"', blogSlug: "xsl-accumulator" }, + { label: "xsl:accumulator-rule", minVersion: "3.0", info: "Rule inside xsl:accumulator", args: 'match="element"', blogSlug: "xsl-accumulator-rule" }, + { label: "xsl:use-accumulators", minVersion: "3.0", info: "Declares which accumulators are used in a template", blogSlug: "xsl-use-accumulators" }, ]; // ─── XPath functions ───────────────────────────────────────────────────────── @@ -95,173 +95,173 @@ export const XPATH_FUNCTIONS = [ { label: "last()", minVersion: "1.0", info: "Returns the size of the context node-set", blogSlug: "xpath-last" }, { label: "position()", minVersion: "1.0", info: "Returns the context position", blogSlug: "xpath-position" }, { label: "count(node-set)", minVersion: "1.0", info: "Returns the number of nodes in a node-set", blogSlug: "xpath-count" }, - { label: "id(string)", minVersion: "1.0", info: "Selects elements by their unique ID attribute" }, - { label: "local-name(node?)", minVersion: "1.0", info: "Returns the local part of a node's name" }, - { label: "namespace-uri(node?)", minVersion: "1.0", info: "Returns the namespace URI of a node" }, - { label: "name(node?)", minVersion: "1.0", info: "Returns the qualified name of a node" }, + { label: "id(string)", minVersion: "1.0", info: "Selects elements by their unique ID attribute", blogSlug: "xpath-id" }, + { label: "local-name(node?)", minVersion: "1.0", info: "Returns the local part of a node's name", blogSlug: "xpath-local-name" }, + { label: "namespace-uri(node?)", minVersion: "1.0", info: "Returns the namespace URI of a node", blogSlug: "xpath-namespace-uri" }, + { label: "name(node?)", minVersion: "1.0", info: "Returns the qualified name of a node", blogSlug: "xpath-name" }, // 1.0 string - { label: "string(object?)", minVersion: "1.0", info: "Converts an object to a string" }, + { label: "string(object?)", minVersion: "1.0", info: "Converts an object to a string", blogSlug: "xpath-string" }, { label: "concat(str, str, ...)", minVersion: "1.0", info: "Concatenates two or more strings", blogSlug: "xpath-concat" }, - { label: "starts-with(str, prefix)", minVersion: "1.0", info: "Returns true if str starts with prefix" }, + { label: "starts-with(str, prefix)", minVersion: "1.0", info: "Returns true if str starts with prefix", blogSlug: "xpath-starts-with" }, { label: "contains(str, substr)", minVersion: "1.0", info: "Returns true if str contains substr", blogSlug: "xpath-contains" }, - { label: "substring-before(str, sep)", minVersion: "1.0", info: "Returns the part of str before the first sep" }, - { label: "substring-after(str, sep)", minVersion: "1.0", info: "Returns the part of str after the first sep" }, + { label: "substring-before(str, sep)", minVersion: "1.0", info: "Returns the part of str before the first sep", blogSlug: "xpath-substring-before" }, + { label: "substring-after(str, sep)", minVersion: "1.0", info: "Returns the part of str after the first sep", blogSlug: "xpath-substring-after" }, { label: "substring(str, start, len?)", minVersion: "1.0", info: "Returns a substring (1-based)", blogSlug: "xpath-substring" }, - { label: "string-length(str?)", minVersion: "1.0", info: "Returns the length of a string" }, - { label: "normalize-space(str?)", minVersion: "1.0", info: "Strips leading/trailing whitespace and collapses internal whitespace" }, - { label: "translate(str, from, to)", minVersion: "1.0", info: "Replaces characters in str: each char in from is replaced by the corresponding char in to" }, + { label: "string-length(str?)", minVersion: "1.0", info: "Returns the length of a string", blogSlug: "xpath-string-length" }, + { label: "normalize-space(str?)", minVersion: "1.0", info: "Strips leading/trailing whitespace and collapses internal whitespace", blogSlug: "xpath-normalize-space" }, + { label: "translate(str, from, to)", minVersion: "1.0", info: "Replaces characters in str: each char in from is replaced by the corresponding char in to", blogSlug: "xpath-translate" }, // 1.0 boolean - { label: "boolean(object)", minVersion: "1.0", info: "Converts an object to boolean" }, - { label: "not(boolean)", minVersion: "1.0", info: "Returns the boolean negation" }, - { label: "true()", minVersion: "1.0", info: "Returns true" }, - { label: "false()", minVersion: "1.0", info: "Returns false" }, - { label: "lang(string)", minVersion: "1.0", info: "Returns true if the context node's language matches" }, + { label: "boolean(object)", minVersion: "1.0", info: "Converts an object to boolean", blogSlug: "xpath-boolean" }, + { label: "not(boolean)", minVersion: "1.0", info: "Returns the boolean negation", blogSlug: "xpath-not" }, + { label: "true()", minVersion: "1.0", info: "Returns true", blogSlug: "xpath-true" }, + { label: "false()", minVersion: "1.0", info: "Returns false", blogSlug: "xpath-false" }, + { label: "lang(string)", minVersion: "1.0", info: "Returns true if the context node's language matches", blogSlug: "xpath-lang" }, // 1.0 number - { label: "number(object?)", minVersion: "1.0", info: "Converts an object to a number" }, + { label: "number(object?)", minVersion: "1.0", info: "Converts an object to a number", blogSlug: "xpath-number" }, { label: "sum(node-set)", minVersion: "1.0", info: "Returns the sum of numeric values in a node-set", blogSlug: "xpath-sum" }, - { label: "floor(number)", minVersion: "1.0", info: "Rounds down to the nearest integer" }, - { label: "ceiling(number)", minVersion: "1.0", info: "Rounds up to the nearest integer" }, - { label: "round(number)", minVersion: "1.0", info: "Rounds to the nearest integer" }, + { label: "floor(number)", minVersion: "1.0", info: "Rounds down to the nearest integer", blogSlug: "xpath-floor" }, + { label: "ceiling(number)", minVersion: "1.0", info: "Rounds up to the nearest integer", blogSlug: "xpath-ceiling" }, + { label: "round(number)", minVersion: "1.0", info: "Rounds to the nearest integer", blogSlug: "xpath-round" }, // XSLT 1.0 extra { label: "key(name, value)", minVersion: "1.0", info: "Looks up nodes using a key defined with xsl:key", blogSlug: "xpath-key" }, - { label: "format-number(num, pattern, decimalFormat?)", minVersion: "1.0", info: "Formats a number using a decimal format pattern" }, + { label: "format-number(num, pattern, decimalFormat?)", minVersion: "1.0", info: "Formats a number using a decimal format pattern", blogSlug: "xpath-format-number" }, { label: "current()", minVersion: "1.0", info: "Returns the current node (differs from . inside predicates)", blogSlug: "xpath-current" }, - { label: "document(uri, node?)", minVersion: "1.0", info: "Loads an external XML document" }, - { label: "unparsed-entity-uri(name)", minVersion: "1.0", info: "Returns the URI of an unparsed entity" }, - { label: "generate-id(node?)", minVersion: "1.0", info: "Generates a unique string ID for a node" }, - { label: "system-property(name)", minVersion: "1.0", info: "Returns XSLT system properties (xsl:version, xsl:vendor, ...)" }, - { label: "element-available(name)", minVersion: "1.0", info: "Returns true if the element is available" }, - { label: "function-available(name)", minVersion: "1.0", info: "Returns true if the function is available" }, + { label: "document(uri, node?)", minVersion: "1.0", info: "Loads an external XML document", blogSlug: "xpath-document" }, + { label: "unparsed-entity-uri(name)", minVersion: "1.0", info: "Returns the URI of an unparsed entity", blogSlug: "xpath-unparsed-entity-uri" }, + { label: "generate-id(node?)", minVersion: "1.0", info: "Generates a unique string ID for a node", blogSlug: "xpath-generate-id" }, + { label: "system-property(name)", minVersion: "1.0", info: "Returns XSLT system properties (xsl:version, xsl:vendor, ...)", blogSlug: "xpath-system-property" }, + { label: "element-available(name)", minVersion: "1.0", info: "Returns true if the element is available", blogSlug: "xpath-element-available" }, + { label: "function-available(name)", minVersion: "1.0", info: "Returns true if the function is available", blogSlug: "xpath-function-available" }, // 2.0 string { label: "string-join(seq, sep?)", minVersion: "2.0", info: "Joins a sequence of strings with a separator", blogSlug: "xpath-string-join" }, { label: "tokenize(str, pattern)", minVersion: "2.0", info: "Splits a string by a regex pattern", blogSlug: "xpath-tokenize" }, { label: "matches(str, pattern, flags?)", minVersion: "2.0", info: "Returns true if str matches a regex", blogSlug: "xpath-matches" }, { label: "replace(str, pattern, replacement, flags?)", minVersion: "2.0", info: "Replaces regex matches in a string", blogSlug: "xpath-replace" }, - { label: "upper-case(str)", minVersion: "2.0", info: "Converts a string to uppercase" }, - { label: "lower-case(str)", minVersion: "2.0", info: "Converts a string to lowercase" }, - { label: "ends-with(str, suffix)", minVersion: "2.0", info: "Returns true if str ends with suffix" }, - { label: "codepoints-to-string(seq)", minVersion: "2.0", info: "Converts Unicode codepoints to a string" }, - { label: "string-to-codepoints(str)", minVersion: "2.0", info: "Converts a string to a sequence of Unicode codepoints" }, - { label: "compare(str1, str2, collation?)", minVersion: "2.0", info: "Compares two strings, returns -1, 0 or 1" }, - { label: "normalize-unicode(str, form?)", minVersion: "2.0", info: "Normalizes a string to a Unicode normalization form" }, + { label: "upper-case(str)", minVersion: "2.0", info: "Converts a string to uppercase", blogSlug: "xpath-upper-case" }, + { label: "lower-case(str)", minVersion: "2.0", info: "Converts a string to lowercase", blogSlug: "xpath-lower-case" }, + { label: "ends-with(str, suffix)", minVersion: "2.0", info: "Returns true if str ends with suffix", blogSlug: "xpath-ends-with" }, + { label: "codepoints-to-string(seq)", minVersion: "2.0", info: "Converts Unicode codepoints to a string", blogSlug: "xpath-codepoints-to-string" }, + { label: "string-to-codepoints(str)", minVersion: "2.0", info: "Converts a string to a sequence of Unicode codepoints", blogSlug: "xpath-string-to-codepoints" }, + { label: "compare(str1, str2, collation?)", minVersion: "2.0", info: "Compares two strings, returns -1, 0 or 1", blogSlug: "xpath-compare" }, + { label: "normalize-unicode(str, form?)", minVersion: "2.0", info: "Normalizes a string to a Unicode normalization form", blogSlug: "xpath-normalize-unicode" }, // 2.0 sequence - { label: "empty(seq)", minVersion: "2.0", info: "Returns true if the sequence is empty" }, - { label: "exists(seq)", minVersion: "2.0", info: "Returns true if the sequence is non-empty" }, - { label: "distinct-values(seq, collation?)", minVersion: "2.0", info: "Returns distinct values from a sequence" }, - { label: "insert-before(seq, pos, ins)", minVersion: "2.0", info: "Inserts items into a sequence at a position" }, - { label: "remove(seq, pos)", minVersion: "2.0", info: "Removes an item at a position from a sequence" }, - { label: "reverse(seq)", minVersion: "2.0", info: "Reverses a sequence" }, - { label: "subsequence(seq, start, len?)", minVersion: "2.0", info: "Returns a subsequence" }, - { label: "unordered(seq)", minVersion: "2.0", info: "Returns items in implementation-defined order (hint to optimizer)" }, - { label: "index-of(seq, value, collation?)", minVersion: "2.0", info: "Returns positions of a value in a sequence" }, - { label: "deep-equal(seq1, seq2, collation?)", minVersion: "2.0", info: "Returns true if two sequences are deeply equal" }, - { label: "zero-or-one(seq)", minVersion: "2.0", info: "Asserts the sequence has 0 or 1 items" }, - { label: "exactly-one(seq)", minVersion: "2.0", info: "Asserts the sequence has exactly 1 item" }, - { label: "one-or-more(seq)", minVersion: "2.0", info: "Asserts the sequence has 1 or more items" }, + { label: "empty(seq)", minVersion: "2.0", info: "Returns true if the sequence is empty", blogSlug: "xpath-empty" }, + { label: "exists(seq)", minVersion: "2.0", info: "Returns true if the sequence is non-empty", blogSlug: "xpath-exists" }, + { label: "distinct-values(seq, collation?)", minVersion: "2.0", info: "Returns distinct values from a sequence", blogSlug: "xpath-distinct-values" }, + { label: "insert-before(seq, pos, ins)", minVersion: "2.0", info: "Inserts items into a sequence at a position", blogSlug: "xpath-insert-before" }, + { label: "remove(seq, pos)", minVersion: "2.0", info: "Removes an item at a position from a sequence", blogSlug: "xpath-remove" }, + { label: "reverse(seq)", minVersion: "2.0", info: "Reverses a sequence", blogSlug: "xpath-reverse" }, + { label: "subsequence(seq, start, len?)", minVersion: "2.0", info: "Returns a subsequence", blogSlug: "xpath-subsequence" }, + { label: "unordered(seq)", minVersion: "2.0", info: "Returns items in implementation-defined order (hint to optimizer)", blogSlug: "xpath-unordered" }, + { label: "index-of(seq, value, collation?)", minVersion: "2.0", info: "Returns positions of a value in a sequence", blogSlug: "xpath-index-of" }, + { label: "deep-equal(seq1, seq2, collation?)", minVersion: "2.0", info: "Returns true if two sequences are deeply equal", blogSlug: "xpath-deep-equal" }, + { label: "zero-or-one(seq)", minVersion: "2.0", info: "Asserts the sequence has 0 or 1 items", blogSlug: "xpath-zero-or-one" }, + { label: "exactly-one(seq)", minVersion: "2.0", info: "Asserts the sequence has exactly 1 item", blogSlug: "xpath-exactly-one" }, + { label: "one-or-more(seq)", minVersion: "2.0", info: "Asserts the sequence has 1 or more items", blogSlug: "xpath-one-or-more" }, // 2.0 numeric - { label: "abs(number)", minVersion: "2.0", info: "Returns the absolute value" }, - { label: "min(seq, collation?)", minVersion: "2.0", info: "Returns the minimum value in a sequence" }, - { label: "max(seq, collation?)", minVersion: "2.0", info: "Returns the maximum value in a sequence" }, - { label: "avg(seq)", minVersion: "2.0", info: "Returns the average of a sequence of numeric values" }, + { label: "abs(number)", minVersion: "2.0", info: "Returns the absolute value", blogSlug: "xpath-abs" }, + { label: "min(seq, collation?)", minVersion: "2.0", info: "Returns the minimum value in a sequence", blogSlug: "xpath-min" }, + { label: "max(seq, collation?)", minVersion: "2.0", info: "Returns the maximum value in a sequence", blogSlug: "xpath-max" }, + { label: "avg(seq)", minVersion: "2.0", info: "Returns the average of a sequence of numeric values", blogSlug: "xpath-avg" }, // 2.0 date/time - { label: "current-date()", minVersion: "2.0", info: "Returns today's date as xs:date" }, - { label: "current-time()", minVersion: "2.0", info: "Returns current time as xs:time" }, - { label: "current-dateTime()", minVersion: "2.0", info: "Returns current date+time as xs:dateTime" }, - { label: "year-from-date(date)", minVersion: "2.0", info: "Extracts the year from an xs:date" }, - { label: "month-from-date(date)", minVersion: "2.0", info: "Extracts the month from an xs:date" }, - { label: "day-from-date(date)", minVersion: "2.0", info: "Extracts the day from an xs:date" }, - { label: "hours-from-time(time)", minVersion: "2.0", info: "Extracts hours from xs:time" }, - { label: "minutes-from-time(time)", minVersion: "2.0", info: "Extracts minutes from xs:time" }, - { label: "seconds-from-time(time)", minVersion: "2.0", info: "Extracts seconds from xs:time" }, + { label: "current-date()", minVersion: "2.0", info: "Returns today's date as xs:date", blogSlug: "xpath-current-date" }, + { label: "current-time()", minVersion: "2.0", info: "Returns current time as xs:time", blogSlug: "xpath-current-time" }, + { label: "current-dateTime()", minVersion: "2.0", info: "Returns current date+time as xs:dateTime", blogSlug: "xpath-current-date-time" }, + { label: "year-from-date(date)", minVersion: "2.0", info: "Extracts the year from an xs:date", blogSlug: "xpath-year-from-date" }, + { label: "month-from-date(date)", minVersion: "2.0", info: "Extracts the month from an xs:date", blogSlug: "xpath-month-from-date" }, + { label: "day-from-date(date)", minVersion: "2.0", info: "Extracts the day from an xs:date", blogSlug: "xpath-day-from-date" }, + { label: "hours-from-time(time)", minVersion: "2.0", info: "Extracts hours from xs:time", blogSlug: "xpath-hours-from-time" }, + { label: "minutes-from-time(time)", minVersion: "2.0", info: "Extracts minutes from xs:time", blogSlug: "xpath-minutes-from-time" }, + { label: "seconds-from-time(time)", minVersion: "2.0", info: "Extracts seconds from xs:time", blogSlug: "xpath-seconds-from-time" }, { label: "format-date(date, picture, lang?, calendar?, place?)", minVersion: "2.0", info: "Formats an xs:date using a picture string", blogSlug: "xpath-format-date" }, - { label: "format-time(time, picture, lang?, calendar?, place?)", minVersion: "2.0", info: "Formats an xs:time using a picture string" }, - { label: "format-dateTime(dateTime, picture, lang?, calendar?, place?)", minVersion: "2.0", info: "Formats an xs:dateTime using a picture string" }, + { label: "format-time(time, picture, lang?, calendar?, place?)", minVersion: "2.0", info: "Formats an xs:time using a picture string", blogSlug: "xpath-format-time" }, + { label: "format-dateTime(dateTime, picture, lang?, calendar?, place?)", minVersion: "2.0", info: "Formats an xs:dateTime using a picture string", blogSlug: "xpath-format-date-time" }, // 2.0 node - { label: "base-uri(node?)", minVersion: "2.0", info: "Returns the base URI of a node" }, - { label: "document-uri(node?)", minVersion: "2.0", info: "Returns the URI of a document node" }, - { label: "nilled(node?)", minVersion: "2.0", info: "Returns true if a node is nilled" }, - { label: "node-name(node?)", minVersion: "2.0", info: "Returns the name of a node as xs:QName" }, + { label: "base-uri(node?)", minVersion: "2.0", info: "Returns the base URI of a node", blogSlug: "xpath-base-uri" }, + { label: "document-uri(node?)", minVersion: "2.0", info: "Returns the URI of a document node", blogSlug: "xpath-document-uri" }, + { label: "nilled(node?)", minVersion: "2.0", info: "Returns true if a node is nilled", blogSlug: "xpath-nilled" }, + { label: "node-name(node?)", minVersion: "2.0", info: "Returns the name of a node as xs:QName", blogSlug: "xpath-node-name" }, // 2.0 QName / misc - { label: "QName(uri, name)", minVersion: "2.0", info: "Creates an xs:QName value" }, - { label: "local-name-from-QName(qname)", minVersion: "2.0", info: "Returns the local part of an xs:QName" }, - { label: "namespace-uri-from-QName(qname)", minVersion: "2.0", info: "Returns the namespace URI of an xs:QName" }, - { label: "prefix-from-QName(qname)", minVersion: "2.0", info: "Returns the prefix of an xs:QName" }, - { label: "resolve-QName(str, element)", minVersion: "2.0", info: "Resolves a lexical QName using in-scope namespaces" }, - { label: "error(qname?, desc?, obj?)", minVersion: "2.0", info: "Raises an error" }, - { label: "trace(value, label?)", minVersion: "2.0", info: "Emits a trace message and returns the value unchanged" }, - { label: "static-base-uri()", minVersion: "2.0", info: "Returns the static base URI of the stylesheet" }, - { label: "implicit-timezone()", minVersion: "2.0", info: "Returns the implicit timezone" }, + { label: "QName(uri, name)", minVersion: "2.0", info: "Creates an xs:QName value", blogSlug: "xpath-qname" }, + { label: "local-name-from-QName(qname)", minVersion: "2.0", info: "Returns the local part of an xs:QName", blogSlug: "xpath-local-name-from-qname" }, + { label: "namespace-uri-from-QName(qname)", minVersion: "2.0", info: "Returns the namespace URI of an xs:QName", blogSlug: "xpath-namespace-uri-from-qname" }, + { label: "prefix-from-QName(qname)", minVersion: "2.0", info: "Returns the prefix of an xs:QName", blogSlug: "xpath-prefix-from-qname" }, + { label: "resolve-QName(str, element)", minVersion: "2.0", info: "Resolves a lexical QName using in-scope namespaces", blogSlug: "xpath-resolve-qname" }, + { label: "error(qname?, desc?, obj?)", minVersion: "2.0", info: "Raises an error", blogSlug: "xpath-error" }, + { label: "trace(value, label?)", minVersion: "2.0", info: "Emits a trace message and returns the value unchanged", blogSlug: "xpath-trace" }, + { label: "static-base-uri()", minVersion: "2.0", info: "Returns the static base URI of the stylesheet", blogSlug: "xpath-static-base-uri" }, + { label: "implicit-timezone()", minVersion: "2.0", info: "Returns the implicit timezone", blogSlug: "xpath-implicit-timezone" }, // 3.0 functional - { label: "apply(func, args)", minVersion: "3.0", info: "Calls a function with an array of arguments" }, - { label: "function-lookup(name, arity)", minVersion: "3.0", info: "Returns a function by name and arity, or the empty sequence" }, - { label: "function-name(func)", minVersion: "3.0", info: "Returns the name of a function item" }, - { label: "function-arity(func)", minVersion: "3.0", info: "Returns the arity of a function item" }, - { label: "for-each(seq, func)", minVersion: "3.0", info: "Applies a function to each item of a sequence" }, - { label: "filter(seq, func)", minVersion: "3.0", info: "Filters a sequence by a predicate function" }, - { label: "fold-left(seq, zero, func)", minVersion: "3.0", info: "Left-fold: accumulates a result over a sequence" }, - { label: "fold-right(seq, zero, func)", minVersion: "3.0", info: "Right-fold: accumulates a result over a sequence (from the right)" }, - { label: "for-each-pair(seq1, seq2, func)", minVersion: "3.0", info: "Applies a function to pairs of items from two sequences" }, - { label: "sort(seq, collation?, key?)", minVersion: "3.0", info: "Sorts a sequence (functional alternative to xsl:sort)" }, - { label: "random-number-generator(seed?)", minVersion: "3.0", info: "Returns a random number generator map" }, + { label: "apply(func, args)", minVersion: "3.0", info: "Calls a function with an array of arguments", blogSlug: "xpath-apply" }, + { label: "function-lookup(name, arity)", minVersion: "3.0", info: "Returns a function by name and arity, or the empty sequence", blogSlug: "xpath-function-lookup" }, + { label: "function-name(func)", minVersion: "3.0", info: "Returns the name of a function item", blogSlug: "xpath-function-name" }, + { label: "function-arity(func)", minVersion: "3.0", info: "Returns the arity of a function item", blogSlug: "xpath-function-arity" }, + { label: "for-each(seq, func)", minVersion: "3.0", info: "Applies a function to each item of a sequence", blogSlug: "xpath-for-each" }, + { label: "filter(seq, func)", minVersion: "3.0", info: "Filters a sequence by a predicate function", blogSlug: "xpath-filter" }, + { label: "fold-left(seq, zero, func)", minVersion: "3.0", info: "Left-fold: accumulates a result over a sequence", blogSlug: "xpath-fold-left" }, + { label: "fold-right(seq, zero, func)", minVersion: "3.0", info: "Right-fold: accumulates a result over a sequence (from the right)", blogSlug: "xpath-fold-right" }, + { label: "for-each-pair(seq1, seq2, func)", minVersion: "3.0", info: "Applies a function to pairs of items from two sequences", blogSlug: "xpath-for-each-pair" }, + { label: "sort(seq, collation?, key?)", minVersion: "3.0", info: "Sorts a sequence (functional alternative to xsl:sort)", blogSlug: "xpath-sort" }, + { label: "random-number-generator(seed?)", minVersion: "3.0", info: "Returns a random number generator map", blogSlug: "xpath-random-number-generator" }, // 3.0 map - { label: "map:merge(maps, options?)", minVersion: "3.0", info: "Merges multiple maps into one" }, - { label: "map:size(map)", minVersion: "3.0", info: "Returns the number of entries in a map" }, - { label: "map:keys(map)", minVersion: "3.0", info: "Returns the keys of a map as a sequence" }, - { label: "map:contains(map, key)", minVersion: "3.0", info: "Returns true if the map contains the key" }, - { label: "map:get(map, key)", minVersion: "3.0", info: "Returns the value for a key in a map, or the empty sequence" }, - { label: "map:put(map, key, value)", minVersion: "3.0", info: "Returns a new map with the key-value pair added or updated" }, - { label: "map:remove(map, keys)", minVersion: "3.0", info: "Returns a new map with specified keys removed" }, - { label: "map:entry(key, value)", minVersion: "3.0", info: "Creates a singleton map with one key-value entry" }, + { label: "map:merge(maps, options?)", minVersion: "3.0", info: "Merges multiple maps into one", blogSlug: "xpath-map-merge" }, + { label: "map:size(map)", minVersion: "3.0", info: "Returns the number of entries in a map", blogSlug: "xpath-map-size" }, + { label: "map:keys(map)", minVersion: "3.0", info: "Returns the keys of a map as a sequence", blogSlug: "xpath-map-keys" }, + { label: "map:contains(map, key)", minVersion: "3.0", info: "Returns true if the map contains the key", blogSlug: "xpath-map-contains" }, + { label: "map:get(map, key)", minVersion: "3.0", info: "Returns the value for a key in a map, or the empty sequence", blogSlug: "xpath-map-get" }, + { label: "map:put(map, key, value)", minVersion: "3.0", info: "Returns a new map with the key-value pair added or updated", blogSlug: "xpath-map-put" }, + { label: "map:remove(map, keys)", minVersion: "3.0", info: "Returns a new map with specified keys removed", blogSlug: "xpath-map-remove" }, + { label: "map:entry(key, value)", minVersion: "3.0", info: "Creates a singleton map with one key-value entry", blogSlug: "xpath-map-entry" }, // 3.0 array - { label: "array:size(array)", minVersion: "3.0", info: "Returns the number of members in an array" }, - { label: "array:get(array, pos)", minVersion: "3.0", info: "Returns the member at a 1-based position" }, - { label: "array:put(array, pos, val)", minVersion: "3.0", info: "Returns a new array with a member replaced" }, - { label: "array:append(array, val)", minVersion: "3.0", info: "Appends a member to an array" }, - { label: "array:head(array)", minVersion: "3.0", info: "Returns the first member of an array" }, - { label: "array:tail(array)", minVersion: "3.0", info: "Returns all but the first member of an array" }, - { label: "array:reverse(array)", minVersion: "3.0", info: "Reverses an array" }, - { label: "array:join(arrays)", minVersion: "3.0", info: "Concatenates multiple arrays" }, - { label: "array:subarray(array, start, length?)", minVersion: "3.0", info: "Returns a sub-array" }, - { label: "array:remove(array, positions)", minVersion: "3.0", info: "Removes members at specified positions" }, - { label: "array:insert-before(array, pos, members)", minVersion: "3.0", info: "Inserts members before a position" }, - { label: "array:for-each(array, func)", minVersion: "3.0", info: "Applies a function to each member of an array" }, - { label: "array:filter(array, func)", minVersion: "3.0", info: "Filters array members by a predicate" }, - { label: "array:fold-left(array, zero, func)", minVersion: "3.0", info: "Left-fold over an array" }, - { label: "array:fold-right(array, zero, func)", minVersion: "3.0", info: "Right-fold over an array" }, - { label: "array:for-each-pair(arr1, arr2, func)", minVersion: "3.0", info: "Applies a function to pairs from two arrays" }, - { label: "array:sort(array, collation?, key?)", minVersion: "3.0", info: "Sorts an array" }, - { label: "array:flatten(items)", minVersion: "3.0", info: "Recursively flattens arrays to a sequence" }, + { label: "array:size(array)", minVersion: "3.0", info: "Returns the number of members in an array", blogSlug: "xpath-array-size" }, + { label: "array:get(array, pos)", minVersion: "3.0", info: "Returns the member at a 1-based position", blogSlug: "xpath-array-get" }, + { label: "array:put(array, pos, val)", minVersion: "3.0", info: "Returns a new array with a member replaced", blogSlug: "xpath-array-put" }, + { label: "array:append(array, val)", minVersion: "3.0", info: "Appends a member to an array", blogSlug: "xpath-array-append" }, + { label: "array:head(array)", minVersion: "3.0", info: "Returns the first member of an array", blogSlug: "xpath-array-head" }, + { label: "array:tail(array)", minVersion: "3.0", info: "Returns all but the first member of an array", blogSlug: "xpath-array-tail" }, + { label: "array:reverse(array)", minVersion: "3.0", info: "Reverses an array", blogSlug: "xpath-array-reverse" }, + { label: "array:join(arrays)", minVersion: "3.0", info: "Concatenates multiple arrays", blogSlug: "xpath-array-join" }, + { label: "array:subarray(array, start, length?)", minVersion: "3.0", info: "Returns a sub-array", blogSlug: "xpath-array-subarray" }, + { label: "array:remove(array, positions)", minVersion: "3.0", info: "Removes members at specified positions", blogSlug: "xpath-array-remove" }, + { label: "array:insert-before(array, pos, members)", minVersion: "3.0", info: "Inserts members before a position", blogSlug: "xpath-array-insert-before" }, + { label: "array:for-each(array, func)", minVersion: "3.0", info: "Applies a function to each member of an array", blogSlug: "xpath-array-for-each" }, + { label: "array:filter(array, func)", minVersion: "3.0", info: "Filters array members by a predicate", blogSlug: "xpath-array-filter" }, + { label: "array:fold-left(array, zero, func)", minVersion: "3.0", info: "Left-fold over an array", blogSlug: "xpath-array-fold-left" }, + { label: "array:fold-right(array, zero, func)", minVersion: "3.0", info: "Right-fold over an array", blogSlug: "xpath-array-fold-right" }, + { label: "array:for-each-pair(arr1, arr2, func)", minVersion: "3.0", info: "Applies a function to pairs from two arrays", blogSlug: "xpath-array-for-each-pair" }, + { label: "array:sort(array, collation?, key?)", minVersion: "3.0", info: "Sorts an array", blogSlug: "xpath-array-sort" }, + { label: "array:flatten(items)", minVersion: "3.0", info: "Recursively flattens arrays to a sequence", blogSlug: "xpath-array-flatten" }, // 3.0 misc - { label: "environment-variable(name)", minVersion: "3.0", info: "Returns the value of an environment variable (if available)" }, - { label: "available-environment-variables()", minVersion: "3.0", info: "Returns the names of available environment variables" }, - { label: "unparsed-text(uri, encoding?)", minVersion: "2.0", info: "Reads a text file and returns it as a string" }, - { label: "unparsed-text-lines(uri, encoding?)", minVersion: "2.0", info: "Reads a text file and returns lines as a sequence" }, - { label: "unparsed-text-available(uri, encoding?)", minVersion: "2.0", info: "Returns true if unparsed-text() would succeed" }, - { label: "uri-collection(uri?)", minVersion: "2.0", info: "Returns a sequence of URIs from a collection" }, - { label: "collection(uri?)", minVersion: "2.0", info: "Returns a sequence of nodes from a collection" }, - { label: "json-doc(uri, options?)", minVersion: "3.0", info: "Parses a JSON document from a URI into an XDM map/array" }, - { label: "json-to-xml(str, options?)", minVersion: "3.0", info: "Converts a JSON string to an XML representation" }, - { label: "xml-to-json(node, options?)", minVersion: "3.0", info: "Converts an XML node to a JSON string" }, - { label: "parse-json(str, options?)", minVersion: "3.0", info: "Parses a JSON string into an XDM map/array/atomic value" }, - { label: "serialize(node, params?)", minVersion: "3.0", info: "Serializes a node or sequence to a string" }, - { label: "parse-xml(str)", minVersion: "2.0", info: "Parses a string as XML and returns a document node" }, - { label: "parse-xml-fragment(str)", minVersion: "2.0", info: "Parses a well-balanced XML fragment" }, - { label: "has-children(node?)", minVersion: "3.0", info: "Returns true if the node has child nodes" }, - { label: "innermost(nodes)", minVersion: "3.0", info: "Returns the nodes that are not ancestors of any other node in the set" }, - { label: "outermost(nodes)", minVersion: "3.0", info: "Returns the nodes that are not descendants of any other node in the set" }, - { label: "path(node?)", minVersion: "3.0", info: "Returns an XPath expression describing the path to the node" }, - { label: "generate-id(node?)", minVersion: "1.0", info: "Returns a unique string identifier for a node" }, - { label: "accumulator-before(name)", minVersion: "3.0", info: "Returns the value of an accumulator before processing the current node" }, - { label: "accumulator-after(name)", minVersion: "3.0", info: "Returns the value of an accumulator after processing the current node" }, - { label: "current-group()", minVersion: "2.0", info: "Returns the current group within xsl:for-each-group" }, - { label: "current-grouping-key()", minVersion: "2.0", info: "Returns the grouping key of the current group" }, - { label: "current-merge-group(source?)", minVersion: "3.0", info: "Returns the current merge group within xsl:merge" }, - { label: "current-merge-key()", minVersion: "3.0", info: "Returns the current merge key within xsl:merge" }, - { label: "current-output-uri()", minVersion: "2.0", info: "Returns the URI of the current output document" }, - { label: "regex-group(n)", minVersion: "2.0", info: "Returns a captured group from xsl:analyze-string" }, - { label: "type-available(type)", minVersion: "2.0", info: "Returns true if a schema type is available" }, - { label: "copy-of(seq)", minVersion: "2.0", info: "Returns a deep copy of a sequence (XQuery/XPath 2.0)" }, - { label: "snapshot(seq)", minVersion: "3.0", info: "Returns a snapshot of the sequence (for streaming)" }, + { label: "environment-variable(name)", minVersion: "3.0", info: "Returns the value of an environment variable (if available)", blogSlug: "xpath-environment-variable" }, + { label: "available-environment-variables()", minVersion: "3.0", info: "Returns the names of available environment variables", blogSlug: "xpath-available-environment-variables" }, + { label: "unparsed-text(uri, encoding?)", minVersion: "2.0", info: "Reads a text file and returns it as a string", blogSlug: "xpath-unparsed-text" }, + { label: "unparsed-text-lines(uri, encoding?)", minVersion: "2.0", info: "Reads a text file and returns lines as a sequence", blogSlug: "xpath-unparsed-text-lines" }, + { label: "unparsed-text-available(uri, encoding?)", minVersion: "2.0", info: "Returns true if unparsed-text() would succeed", blogSlug: "xpath-unparsed-text-available" }, + { label: "uri-collection(uri?)", minVersion: "2.0", info: "Returns a sequence of URIs from a collection", blogSlug: "xpath-uri-collection" }, + { label: "collection(uri?)", minVersion: "2.0", info: "Returns a sequence of nodes from a collection", blogSlug: "xpath-collection" }, + { label: "json-doc(uri, options?)", minVersion: "3.0", info: "Parses a JSON document from a URI into an XDM map/array", blogSlug: "xpath-json-doc" }, + { label: "json-to-xml(str, options?)", minVersion: "3.0", info: "Converts a JSON string to an XML representation", blogSlug: "xpath-json-to-xml" }, + { label: "xml-to-json(node, options?)", minVersion: "3.0", info: "Converts an XML node to a JSON string", blogSlug: "xpath-xml-to-json" }, + { label: "parse-json(str, options?)", minVersion: "3.0", info: "Parses a JSON string into an XDM map/array/atomic value", blogSlug: "xpath-parse-json" }, + { label: "serialize(node, params?)", minVersion: "3.0", info: "Serializes a node or sequence to a string", blogSlug: "xpath-serialize" }, + { label: "parse-xml(str)", minVersion: "2.0", info: "Parses a string as XML and returns a document node", blogSlug: "xpath-parse-xml" }, + { label: "parse-xml-fragment(str)", minVersion: "2.0", info: "Parses a well-balanced XML fragment", blogSlug: "xpath-parse-xml-fragment" }, + { label: "has-children(node?)", minVersion: "3.0", info: "Returns true if the node has child nodes", blogSlug: "xpath-has-children" }, + { label: "innermost(nodes)", minVersion: "3.0", info: "Returns the nodes that are not ancestors of any other node in the set", blogSlug: "xpath-innermost" }, + { label: "outermost(nodes)", minVersion: "3.0", info: "Returns the nodes that are not descendants of any other node in the set", blogSlug: "xpath-outermost" }, + { label: "path(node?)", minVersion: "3.0", info: "Returns an XPath expression describing the path to the node", blogSlug: "xpath-path" }, + { label: "generate-id(node?)", minVersion: "1.0", info: "Returns a unique string identifier for a node", blogSlug: "xpath-generate-id" }, + { label: "accumulator-before(name)", minVersion: "3.0", info: "Returns the value of an accumulator before processing the current node", blogSlug: "xpath-accumulator-before" }, + { label: "accumulator-after(name)", minVersion: "3.0", info: "Returns the value of an accumulator after processing the current node", blogSlug: "xpath-accumulator-after" }, + { label: "current-group()", minVersion: "2.0", info: "Returns the current group within xsl:for-each-group", blogSlug: "xpath-current-group" }, + { label: "current-grouping-key()", minVersion: "2.0", info: "Returns the grouping key of the current group", blogSlug: "xpath-current-grouping-key" }, + { label: "current-merge-group(source?)", minVersion: "3.0", info: "Returns the current merge group within xsl:merge", blogSlug: "xpath-current-merge-group" }, + { label: "current-merge-key()", minVersion: "3.0", info: "Returns the current merge key within xsl:merge", blogSlug: "xpath-current-merge-key" }, + { label: "current-output-uri()", minVersion: "2.0", info: "Returns the URI of the current output document", blogSlug: "xpath-current-output-uri" }, + { label: "regex-group(n)", minVersion: "2.0", info: "Returns a captured group from xsl:analyze-string", blogSlug: "xpath-regex-group" }, + { label: "type-available(type)", minVersion: "2.0", info: "Returns true if a schema type is available", blogSlug: "xpath-type-available" }, + { label: "copy-of(seq)", minVersion: "2.0", info: "Returns a deep copy of a sequence (XQuery/XPath 2.0)", blogSlug: "xpath-copy-of" }, + { label: "snapshot(seq)", minVersion: "3.0", info: "Returns a snapshot of the sequence (for streaming)", blogSlug: "xpath-snapshot" }, ]; const VERSION_ORDER = { "1.0": 1, "2.0": 2, "3.0": 3 }; diff --git a/site/content/xslt/functions/xpath-abs.md b/site/content/xslt/functions/xpath-abs.md new file mode 100644 index 00000000..07d61196 --- /dev/null +++ b/site/content/xslt/functions/xpath-abs.md @@ -0,0 +1,107 @@ +--- +title: "abs()" +description: "Returns the absolute value of a numeric argument, removing any negative sign while preserving the numeric type." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "numeric function" +syntax: "abs(number)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`abs()` returns the absolute (non-negative) value of its argument. The result has the same type as the input: `xs:integer` in gives `xs:integer` out, `xs:double` in gives `xs:double` out. If the argument is the empty sequence, the empty sequence is returned. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `number` | xs:numeric? | Yes | The numeric value whose absolute value is required. | + +## Return value + +`xs:numeric?` — same type and precision as the input, but non-negative. Returns the empty sequence if the argument is the empty sequence. + +## Examples + +### Absolute value of a negative attribute + +**Input XML:** +```xml + + + -42 + 17 + -3.14 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output:** +```xml + + 42 + 17 + 3.14 + +``` + +### Computing deviation from a target value + +**Stylesheet:** +```xml + + + + + + + + + + + + + +``` + +**Output (for values -42, 17, -3.14 against target 10):** +```xml + + 52 + 7 + 13.14 + +``` + +## Notes + +- `abs()` is defined in XPath 2.0 and is not available in XSLT 1.0. In XSLT 1.0, absolute value required a workaround such as `translate(., '-', '')` or a conditional expression. +- The function preserves numeric type: `abs(xs:float(-1.0))` returns `xs:float(1.0)`. +- `abs(xs:double('NaN'))` returns `NaN`; `abs(xs:double('-INF'))` returns `INF`. + +## See also + +- [avg()](../xpath-avg) +- [min()](../xpath-min) +- [max()](../xpath-max) diff --git a/site/content/xslt/functions/xpath-accumulator-after.md b/site/content/xslt/functions/xpath-accumulator-after.md new file mode 100644 index 00000000..7959579d --- /dev/null +++ b/site/content/xslt/functions/xpath-accumulator-after.md @@ -0,0 +1,116 @@ +--- +title: "accumulator-after()" +description: "Returns the value of a named accumulator computed after processing the current node in streaming mode." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "node function" +syntax: "accumulator-after(name)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`accumulator-after()` returns the value of a named accumulator as computed just after all accumulator rules for the current node have been applied. It is the counterpart to `accumulator-before()`: where `accumulator-before()` gives the value before the node's rule fires, `accumulator-after()` gives the updated value reflecting the current node's contribution. + +The function is only meaningful in contexts where an accumulator rule for the named accumulator has a match for the current node. If no rule matches, before and after values are identical. + +Both accumulator functions are essential for streaming transformations where you cannot revisit nodes. They allow you to carry state forward through the document without storing nodes in memory. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `name` | xs:string | Yes | The name of the accumulator to read. | + +## Return value + +The declared return type of the named accumulator — the value computed after the current node's accumulator rule has been applied. + +## Examples + +### Cumulative total after each node + +**Input XML:** +```xml + + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + + + +``` + +### Final accumulator value on the parent + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml +200 +``` + +## Notes + +- `accumulator-after()` on a node with no matching accumulator rule returns the same value as `accumulator-before()`. +- Accumulators must be listed in the `use-accumulators` attribute of the template or `xsl:use-accumulators` instruction to be active for that template. +- Accumulators are phase-ordered: all accumulator rules are applied before any template generates output for a given node. +- In XSLT 3.0 packages, accumulators can be imported and their visibility controlled with `xsl:expose`. + +## See also + +- [accumulator-before()](../xpath-accumulator-before) +- [snapshot()](../xpath-snapshot) +- [xsl:use-accumulators](../xsl-use-accumulators) diff --git a/site/content/xslt/functions/xpath-accumulator-before.md b/site/content/xslt/functions/xpath-accumulator-before.md new file mode 100644 index 00000000..88deac8f --- /dev/null +++ b/site/content/xslt/functions/xpath-accumulator-before.md @@ -0,0 +1,119 @@ +--- +title: "accumulator-before()" +description: "Returns the value of a named accumulator computed before processing the current node in streaming mode." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "node function" +syntax: "accumulator-before(name)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`accumulator-before()` returns the value of a named accumulator as it was just before the current node was processed. Accumulators are XSLT 3.0 constructs that compute running values as the processor traverses a document — similar to a running total or state machine. The "before" value reflects the accumulator state prior to applying any accumulator rule for the current node. + +The function is used inside `xsl:accumulator-rule` actions and in template rules that access accumulator state. The `name` argument is a string literal matching the `name` attribute of an `xsl:accumulator` declaration. + +For the function to be available in a template, the template must declare the accumulator in its `use-accumulators` attribute (or via `xsl:use-accumulators`). + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `name` | xs:string | Yes | The name of the accumulator to read. | + +## Return value + +The declared return type of the named accumulator — the value computed just before the current node is entered. + +## Examples + +### Running total accumulator + +**Input XML:** +```xml + + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + + + +``` + +### Comparing before and after values + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + +``` + +## Notes + +- `accumulator-before()` reads the accumulator value before the node's rule fires; `accumulator-after()` reads it after. +- The accumulator must be declared with `xsl:accumulator` at the top level and listed in the template's `use-accumulators` attribute. +- Accumulators are primarily designed for streaming, but they also work in non-streaming transformations. +- The initial value is used as the "before" value for the first matched node. + +## See also + +- [accumulator-after()](../xpath-accumulator-after) +- [snapshot()](../xpath-snapshot) +- [xsl:use-accumulators](../xsl-use-accumulators) diff --git a/site/content/xslt/functions/xpath-apply.md b/site/content/xslt/functions/xpath-apply.md new file mode 100644 index 00000000..204036b0 --- /dev/null +++ b/site/content/xslt/functions/xpath-apply.md @@ -0,0 +1,118 @@ +--- +title: "apply()" +description: "Calls a function item with arguments supplied as an array, enabling dynamic dispatch with a variable argument list." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "higher-order function" +syntax: "apply(function, array-of-args)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`apply()` invokes a function item, passing its arguments as members of an array. This enables dynamic function calls where both the function and its argument list are determined at runtime. The number of array members must match the arity of the function, otherwise a type error is raised. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `function` | function(*) | Yes | The function item to invoke. | +| `array-of-args` | array(*) | Yes | An array whose members are the arguments to pass. Member count must equal the function arity. | + +## Return value + +`item()*` — the result returned by the invoked function. + +## Examples + +### Dynamic dispatch with apply() + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 10 + +``` + +### Applying a selected operation dynamically + +**Input XML:** +```xml + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + HELLO + world + +``` + +## Notes + +- `apply()` is defined in XPath 3.0 / XSLT 3.0. It is not available in XSLT 2.0 or earlier. +- The function arity must exactly match the number of members in the array; a mismatch causes `err:FOAP0001`. +- `apply()` is the complement of inline function items and partial function application. +- Useful for implementing dispatch tables and strategy patterns in XSLT. + +## See also + +- [function-lookup()](../xpath-function-lookup) +- [function-name()](../xpath-function-name) +- [function-arity()](../xpath-function-arity) +- [for-each()](../xpath-for-each) diff --git a/site/content/xslt/functions/xpath-array-append.md b/site/content/xslt/functions/xpath-array-append.md new file mode 100644 index 00000000..9313788f --- /dev/null +++ b/site/content/xslt/functions/xpath-array-append.md @@ -0,0 +1,119 @@ +--- +title: "array:append()" +description: "Returns a new array with an additional member appended at the end." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:append(array, appendage)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:append()` returns a new array that is a copy of the input array with the `appendage` value added as a new final member. The appendage is added as a single member regardless of whether it is a sequence, making it distinct from `array:join()` which concatenates arrays. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The source array. | +| `appendage` | item()* | Yes | The value to add as the new last member. | + +## Return value + +`array(*)` — a new array with `array:size()` increased by 1. + +## Examples + +### Building an array by appending + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + alpha + beta + gamma + delta + +``` + +### Accumulating results into an array with fold-left + +**Input XML:** +```xml + + + 85 + 92 + 78 + 96 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 4 + 96 + +``` + +## Notes + +- The `appendage` is added as a single member; if it is a sequence `(1,2)`, the new member is that two-item sequence, not two separate members. +- To concatenate two arrays end-to-end, use `array:join(($arr1, $arr2))`. +- Arrays are immutable; `array:append()` always returns a new array. + +## See also + +- [array:join()](../xpath-array-join) +- [array:insert-before()](../xpath-array-insert-before) +- [array:remove()](../xpath-array-remove) +- [array:size()](../xpath-array-size) +- [xsl:array](../xsl-array) +- [xsl:array-member](../xsl-array-member) diff --git a/site/content/xslt/functions/xpath-array-filter.md b/site/content/xslt/functions/xpath-array-filter.md new file mode 100644 index 00000000..ab32733b --- /dev/null +++ b/site/content/xslt/functions/xpath-array-filter.md @@ -0,0 +1,131 @@ +--- +title: "array:filter()" +description: "Returns a new array containing only the members for which a predicate function returns true." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:filter(array, predicate)" +tags: ["xslt", "reference", "xslt3", "xpath"] +--- + +## Description + +`array:filter()` applies a predicate function to each member of the input array and returns a new array containing only the members for which the predicate returns `true`. The order of surviving members is preserved and the original array is not modified. + +The predicate is an inline or named function with signature `function(item()*) as xs:boolean`. Each member of the array—whether it is a single item or a sequence—is passed to the predicate as a whole unit. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | `array(*)` | Yes | The source array whose members are tested. | +| `predicate` | `function(item()*) as xs:boolean` | Yes | A function that returns true for members to keep. | + +## Return value + +`array(*)` — a new array containing only the members for which the predicate returned `true`. The size may be zero if no members pass. + +## Examples + +### Filtering numbers greater than 5 + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 8 + 4 + 7 + 9 + 6 + 8 + +``` + +### Filtering non-empty strings from an XML source + +**Input XML:** +```xml + + + xslt + + xpath + + saxon + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + xslt + xpath + saxon + +``` + +## Notes + +- Each array member is passed as a whole unit to the predicate. A member that is itself a sequence is passed as that sequence, not as individual items. +- `array:filter()` always returns a new array; the source array is unmodified. +- To apply a transformation rather than a selection, use `array:for-each()`. +- If no member satisfies the predicate, an empty array `[]` is returned. + +## See also + +- [array:for-each()](../xpath-array-for-each) +- [array:fold-left()](../xpath-array-fold-left) +- [array:remove()](../xpath-array-remove) +- [array:size()](../xpath-array-size) diff --git a/site/content/xslt/functions/xpath-array-flatten.md b/site/content/xslt/functions/xpath-array-flatten.md new file mode 100644 index 00000000..52bbe848 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-flatten.md @@ -0,0 +1,128 @@ +--- +title: "array:flatten()" +description: "Recursively flattens nested arrays into a single flat sequence of atomic items and nodes." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:flatten(items)" +tags: ["xslt", "reference", "xslt3", "xpath"] +--- + +## Description + +`array:flatten()` takes a sequence of items that may contain arrays—including arrays nested inside arrays—and returns a flat sequence in which every array has been dissolved. Non-array items (strings, integers, nodes, maps, etc.) pass through unchanged; only array wrappers are removed. + +The recursion is unbounded: a three-level-deep nesting such as `[[1, [2, 3]], [4]]` is fully flattened to `(1, 2, 3, 4)`. This makes `array:flatten()` useful when assembling arrays incrementally or when consuming data structures of unknown depth. + +Note that the result is a **sequence**, not an array. Wrap it in `array:join()` if an array is required. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `items` | `item()*` | Yes | A sequence of items, which may include arrays at any depth of nesting. | + +## Return value + +`item()*` — a flat sequence with all array wrappers removed. Maps are not unwrapped; only arrays are affected. + +## Examples + +### Flattening nested integer arrays + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 1, 2, 3, 4, 5, 6 + 21 + +``` + +### Normalising a heterogeneous collection before processing + +**Input XML:** +```xml + + + + alpha + beta + + + gamma + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + alpha + beta + gamma + +``` + +## Notes + +- Only arrays are unwrapped. Maps, even though they are also XDM structured types, are left intact. +- The function accepts a plain sequence as its argument, not only an array. Items in the sequence that are not arrays pass through unchanged. +- Members that are sequences (e.g. a member holding `(1, 2)`) remain as sequences inside the result because they are not themselves arrays. +- To convert the resulting sequence back into an array, use `array:join()` with individual wrapping: `array:join(for $x in array:flatten($arr) return [$x])`. + +## See also + +- [array:join()](../xpath-array-join) +- [array:for-each()](../xpath-array-for-each) +- [array:fold-left()](../xpath-array-fold-left) diff --git a/site/content/xslt/functions/xpath-array-fold-left.md b/site/content/xslt/functions/xpath-array-fold-left.md new file mode 100644 index 00000000..ec211c81 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-fold-left.md @@ -0,0 +1,127 @@ +--- +title: "array:fold-left()" +description: "Accumulates a result by applying a function to each array member from left to right, starting with a seed value." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:fold-left(array, zero, function)" +tags: ["xslt", "reference", "xslt3", "xpath"] +--- + +## Description + +`array:fold-left()` processes an array from its first member to its last, threading an accumulator through each step. For each member, the supplied function is called with the current accumulator value and the current member; its return value becomes the accumulator for the next step. After all members have been processed, the final accumulator value is returned. + +When the array is empty, the `zero` (seed) value is returned unchanged without calling the function. This mirrors the mathematical notion of a left fold and is equivalent to the XPath 3.0 `fold-left()` function applied to sequences. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | `array(*)` | Yes | The array to fold. | +| `zero` | `item()*` | Yes | The initial accumulator value, returned as-is when the array is empty. | +| `function` | `function(item()*, item()*) as item()*` | Yes | A function taking `(accumulator, member)` and returning the new accumulator. | + +## Return value + +`item()*` — the final accumulated result after processing all members. + +## Examples + +### Summing an array of numbers + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 30 + 10 + +``` + +### Building a CSV line from an array of strings + +**Input XML:** +```xml + + + Alice + Engineering + London + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + +``` + +**Output:** +``` +Alice,Engineering,London +``` + +## Notes + +- `array:fold-left()` and `array:fold-right()` differ in the direction of traversal, which matters for non-commutative operations such as string concatenation or subtraction. +- The zero value type must be compatible with the accumulator type expected by the function; Saxon enforces type consistency at runtime. +- For very large arrays, folding is generally more efficient than recursive template calls because it avoids XSL overhead. +- The XPath 3.0 `fold-left()` function (without the `array:` prefix) performs the same operation over sequences rather than arrays. + +## See also + +- [array:fold-right()](../xpath-array-fold-right) +- [array:for-each()](../xpath-array-for-each) +- [array:filter()](../xpath-array-filter) +- [array:size()](../xpath-array-size) diff --git a/site/content/xslt/functions/xpath-array-fold-right.md b/site/content/xslt/functions/xpath-array-fold-right.md new file mode 100644 index 00000000..3527a51f --- /dev/null +++ b/site/content/xslt/functions/xpath-array-fold-right.md @@ -0,0 +1,127 @@ +--- +title: "array:fold-right()" +description: "Accumulates a result by applying a function to each array member from right to left, starting with a seed value." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:fold-right(array, zero, function)" +tags: ["xslt", "reference", "xslt3", "xpath"] +--- + +## Description + +`array:fold-right()` traverses an array from its last member to its first, threading an accumulator through each step. For each member the supplied function is called with the current member and the current accumulator; its return value becomes the accumulator for the next (earlier) member. The final accumulator value after processing the first member is returned. + +When the array is empty the `zero` seed is returned unchanged. The key distinction from `array:fold-left()` is the traversal direction and the argument order to the function: the member comes first, then the accumulator. This matters for operations that are not commutative, such as building a prefix string or constructing a right-associated structure. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | `array(*)` | Yes | The array to fold. | +| `zero` | `item()*` | Yes | The initial accumulator value, returned as-is when the array is empty. | +| `function` | `function(item()*, item()*) as item()*` | Yes | A function taking `(member, accumulator)` and returning the new accumulator. | + +## Return value + +`item()*` — the final accumulated result after processing all members from right to left. + +## Examples + +### Concatenating strings in reverse accumulation order + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + one > two > three > four + one > two > three > four + +``` + +### Building a nested XML structure from right to left + +**Input XML:** +```xml + + + root + section + paragraph + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output:** +```xml +root / section / paragraph / END +``` + +## Notes + +- The function signature for `array:fold-right()` is `function(member, accumulator)`, while `array:fold-left()` uses `function(accumulator, member)`. Confusing the argument order is a common mistake. +- For commutative operations (addition, min, max) the fold direction produces the same result; for string concatenation and list building the direction matters. +- Like all array functions, the operation returns a new value; no existing array is modified. +- The XPath 3.0 sequence function `fold-right()` (without `array:` prefix) is the equivalent for ordinary sequences. + +## See also + +- [array:fold-left()](../xpath-array-fold-left) +- [array:for-each()](../xpath-array-for-each) +- [array:filter()](../xpath-array-filter) diff --git a/site/content/xslt/functions/xpath-array-for-each-pair.md b/site/content/xslt/functions/xpath-array-for-each-pair.md new file mode 100644 index 00000000..79dcdb2d --- /dev/null +++ b/site/content/xslt/functions/xpath-array-for-each-pair.md @@ -0,0 +1,115 @@ +--- +title: "array:for-each-pair()" +description: "Returns a new array by applying the function to corresponding members of two arrays of the same size." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:for-each-pair(array1, array2, function)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:for-each-pair()` applies a two-argument function to corresponding members of two arrays and returns a new array of the results. The function is called with the member from the first array and the member from the second array at each position. The two input arrays must have the same size; if they differ, a dynamic error is raised. + +This function is the array analogue of the `for-each-pair()` higher-order function for sequences. It enables pairwise operations — such as computing differences, combining data from parallel arrays, or zipping two arrays together. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array1` | array(*) | Yes | The first input array. | +| `array2` | array(*) | Yes | The second input array, must be the same size as array1. | +| `function` | function(item()*, item()*) as item()* | Yes | A two-argument function applied to corresponding members. | + +## Return value + +`array(*)` — a new array of the same size, where each member is the result of applying the function to the corresponding pair of members. + +## Examples + +### Adding corresponding elements + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 11 + 22 + 33 + +``` + +### Zipping names with scores + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Alice:95 + Bob:82 + Carol:91 + +``` + +## Notes + +- Both arrays must have the same number of members. If the sizes differ, a dynamic error is raised. +- Each member is passed to the function as a sequence — a single-item member is a sequence of length one. +- The result array has the same size as the inputs. +- To process a single array with a two-argument function that also tracks the index, combine `array:for-each-pair()` with a position array created via `array:join(for $i in 1 to array:size($a) return [$i])`. + +## See also + +- [array:for-each()](../xpath-array-for-each) +- [array:filter()](../xpath-array-filter) +- [array:fold-left()](../xpath-array-fold-left) +- [array:flatten()](../xpath-array-flatten) diff --git a/site/content/xslt/functions/xpath-array-for-each.md b/site/content/xslt/functions/xpath-array-for-each.md new file mode 100644 index 00000000..ba951e4a --- /dev/null +++ b/site/content/xslt/functions/xpath-array-for-each.md @@ -0,0 +1,115 @@ +--- +title: "array:for-each()" +description: "Returns a new array where each member is the result of applying the function to the corresponding member of the input array." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:for-each(array, function)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:for-each()` applies a function to each member of an array and returns a new array of the same size, where each member is the result of the function applied to the corresponding input member. The original array is not modified. + +The function argument takes a single parameter: the current array member, which is a sequence. The function may return any XDM value — a single item, a sequence, or even an empty sequence — and the result becomes the corresponding member of the output array. + +`array:for-each()` is the array equivalent of the sequence-level `for-each()` higher-order function, but it preserves array structure rather than flattening to a sequence. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The input array. | +| `function` | function(item()*) as item()* | Yes | A function applied to each member. | + +## Return value + +`array(*)` — a new array of the same size as the input, with each member replaced by the function result. + +## Examples + +### Squaring each element + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 1 + 4 + 9 + 16 + 25 + +``` + +### Uppercasing string members + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + ALPHA + BETA + GAMMA + +``` + +## Notes + +- `array:for-each()` always produces a new array of the same size as the input; it cannot drop or add members. Use `array:filter()` to remove members. +- Named functions can be referenced using the function-reference syntax (`name#arity`) as shown in the second example. +- Unlike `array:fold-left()`, `array:for-each()` does not accumulate state across members; each call is independent. +- An empty array produces an empty array. + +## See also + +- [array:filter()](../xpath-array-filter) +- [array:fold-left()](../xpath-array-fold-left) +- [array:for-each-pair()](../xpath-array-for-each-pair) +- [array:flatten()](../xpath-array-flatten) diff --git a/site/content/xslt/functions/xpath-array-get.md b/site/content/xslt/functions/xpath-array-get.md new file mode 100644 index 00000000..a89fc8a7 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-get.md @@ -0,0 +1,110 @@ +--- +title: "array:get()" +description: "Returns the member of an array at a specified 1-based position." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:get(array, position)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:get()` retrieves the member at the given 1-based integer position in an array. If the position is less than 1 or greater than the array size, error `err:FOAY0001` is raised. An alternative shorthand is `$array($position)` using function-call syntax. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The array to access. | +| `position` | xs:integer | Yes | The 1-based position of the member to retrieve. | + +## Return value + +`item()*` — the member at the given position (may be a sequence if the member is a sequence). + +## Examples + +### Accessing array elements by position + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + red + blue + yellow + +``` + +### Iterating with positional access + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 123 + 456 + 789 + +``` + +## Notes + +- Positions are 1-based (not 0-based), consistent with XPath sequence indexing. +- Out-of-bounds access raises `err:FOAY0001`; use `array:size()` to guard. +- The shorthand `$array($pos)` is syntactic sugar for `array:get($array, $pos)`. + +## See also + +- [array:size()](../xpath-array-size) +- [array:head()](../xpath-array-head) +- [array:put()](../xpath-array-put) +- [array:subarray()](../xpath-array-subarray) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-head.md b/site/content/xslt/functions/xpath-array-head.md new file mode 100644 index 00000000..a4402749 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-head.md @@ -0,0 +1,104 @@ +--- +title: "array:head()" +description: "Returns the first member of an array; raises an error if the array is empty." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:head(array)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:head()` returns the value of the first member of an array. If the array is empty, error `err:FOAY0001` is raised. Together with `array:tail()`, it supports recursive pattern-matching style processing over arrays. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The array whose first member is to be returned. | + +## Return value + +`item()*` — the first member (which may itself be a sequence). + +## Examples + +### Accessing the first element safely + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + first + +``` + +### Recursive processing with head and tail + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 100 + +``` + +## Notes + +- Equivalent to `array:get($array, 1)`. +- Raises `err:FOAY0001` on an empty array; guard with `array:size($arr) gt 0`. +- Pair with `array:tail()` for list-processing patterns. + +## See also + +- [array:tail()](../xpath-array-tail) +- [array:get()](../xpath-array-get) +- [array:size()](../xpath-array-size) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-insert-before.md b/site/content/xslt/functions/xpath-array-insert-before.md new file mode 100644 index 00000000..f50e3d63 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-insert-before.md @@ -0,0 +1,108 @@ +--- +title: "array:insert-before()" +description: "Returns a new array with the given members inserted before the specified 1-based position." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:insert-before(array, position, members)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:insert-before()` returns a new array formed by inserting one or more new members into the input array just before the specified position. The `position` argument is 1-based. Inserting before position 1 prepends to the array; inserting before `array:size($array) + 1` appends to the array. + +The `members` argument is treated as a sequence of new array members to insert, each becoming a separate member of the result array. This means the result array's size is `array:size(array) + count(members-sequence)`. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The source array. | +| `position` | xs:integer | Yes | The 1-based position before which to insert. | +| `members` | item()* | Yes | The sequence of new members to insert. Each item in the sequence becomes a separate array member. | + +## Return value + +`array(*)` — a new array with the inserted members, larger than the original. + +## Examples + +### Inserting at the beginning + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output:** +``` +A B C D +``` + +### Inserting in the middle + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 1 + 2 + 3 + 4 + 5 + 6 + +``` + +## Notes + +- Inserting before position `array:size($array) + 1` is equivalent to appending; use `array:append()` for clarity. +- The `members` argument is a sequence; each item in the sequence becomes a separate array member. To insert a single member that is itself a sequence, wrap it in an array and use `array:join()`. +- Positions outside the range 1 to `size + 1` raise a dynamic error. +- The source array is not modified; `array:insert-before()` always returns a new array. + +## See also + +- [array:remove()](../xpath-array-remove) +- [array:append()](../xpath-array-append) +- [array:flatten()](../xpath-array-flatten) +- [array:size()](../xpath-array-size) diff --git a/site/content/xslt/functions/xpath-array-join.md b/site/content/xslt/functions/xpath-array-join.md new file mode 100644 index 00000000..aee594da --- /dev/null +++ b/site/content/xslt/functions/xpath-array-join.md @@ -0,0 +1,121 @@ +--- +title: "array:join()" +description: "Concatenates a sequence of arrays into a single array by combining all their members." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:join(arrays)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:join()` takes a sequence of arrays and returns a single array whose members are all the members of the input arrays concatenated in order. An empty sequence of arrays returns an empty array. This is distinct from `array:append()` which adds a single new member. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `arrays` | array(*)* | Yes | A sequence of arrays to concatenate. | + +## Return value + +`array(*)` — a new array containing all members of all input arrays in order. + +## Examples + +### Joining two arrays + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + a + b + c + d + e + f + +``` + +### Building an array from chunked XML data + +**Input XML:** +```xml + + + 12 + 34 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 1234 + +``` + +## Notes + +- `array:join(())` returns an empty array `[]`. +- Unlike `array:append()`, which adds one item as a single member, `array:join()` merges the members of each array. +- The result length equals the sum of the sizes of all input arrays. + +## See also + +- [array:append()](../xpath-array-append) +- [array:subarray()](../xpath-array-subarray) +- [array:size()](../xpath-array-size) +- [array:flatten()](../xpath-array-flatten) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-put.md b/site/content/xslt/functions/xpath-array-put.md new file mode 100644 index 00000000..187828ba --- /dev/null +++ b/site/content/xslt/functions/xpath-array-put.md @@ -0,0 +1,115 @@ +--- +title: "array:put()" +description: "Returns a new array with the member at a given position replaced by a new value." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:put(array, position, value)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:put()` produces a new array identical to the input except that the member at the specified 1-based position is replaced with the new value. Arrays are immutable in XDM; the original array is not modified. Out-of-range positions raise `err:FOAY0001`. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The source array. | +| `position` | xs:integer | Yes | The 1-based position of the member to replace. | +| `value` | item()* | Yes | The new value for that position. | + +## Return value + +`array(*)` — a new array with the member at `position` replaced by `value`. + +## Examples + +### Replacing a member in an array + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + a + B + c + d + +``` + +### Updating JSON-like array data + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + original-1 + updated-value + original-3 + +``` + +## Notes + +- Array positions are 1-based. Position `0` or greater than `array:size()` raises `err:FOAY0001`. +- The new value can be any XDM value, including a sequence (which becomes a single multi-item member). +- Arrays are immutable; the result is always a new array. + +## See also + +- [array:get()](../xpath-array-get) +- [array:append()](../xpath-array-append) +- [array:remove()](../xpath-array-remove) +- [array:insert-before()](../xpath-array-insert-before) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-remove.md b/site/content/xslt/functions/xpath-array-remove.md new file mode 100644 index 00000000..3fc91213 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-remove.md @@ -0,0 +1,104 @@ +--- +title: "array:remove()" +description: "Returns a new array with the members at the specified 1-based positions removed." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:remove(array, positions)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:remove()` returns a new array with specified members omitted. The `positions` argument is a sequence of 1-based integers identifying the members to remove. Positions may be supplied in any order; duplicates are ignored. Members not listed in `positions` are retained in their original relative order. + +If `positions` is the empty sequence, the function returns a copy of the input array unchanged. All specified positions must be valid (between 1 and `array:size(array)` inclusive); an out-of-range position raises a dynamic error. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The source array. | +| `positions` | xs:integer* | Yes | A sequence of 1-based positions to remove. | + +## Return value + +`array(*)` — a new array with the specified members removed, preserving the relative order of remaining members. + +## Examples + +### Removing a single member + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output:** +``` +A C D +``` + +### Removing multiple members + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 20 + 40 + 50 + +``` + +## Notes + +- `array:remove()` removes by position, not by value. To remove by value, combine `array:filter()` with a value comparison. +- Positions are 1-based, consistent with all other array functions. +- Duplicate positions in the `positions` sequence are silently ignored. +- Removing all positions results in an empty array `[]`; removing no positions (`()`) returns a copy of the input. + +## See also + +- [array:insert-before()](../xpath-array-insert-before) +- [array:filter()](../xpath-array-filter) +- [array:subarray()](../xpath-array-subarray) +- [array:size()](../xpath-array-size) diff --git a/site/content/xslt/functions/xpath-array-reverse.md b/site/content/xslt/functions/xpath-array-reverse.md new file mode 100644 index 00000000..b893af14 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-reverse.md @@ -0,0 +1,121 @@ +--- +title: "array:reverse()" +description: "Returns a new array with the members in reverse order." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:reverse(array)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:reverse()` returns a new array whose members are in the reverse order of the input array. The function is a convenience over manual head/tail recursion and operates on the array structure directly, preserving each member as-is (including members that are sequences). + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The array whose members are to be reversed. | + +## Return value + +`array(*)` — a new array with members in reverse order; an empty array if the input is empty. + +## Examples + +### Reversing a simple array + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 50 + 40 + 30 + 20 + 10 + +``` + +### Reversing a sorted array for descending order + +**Input XML:** +```xml + + + 88429567 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 95 + 88 + 67 + 42 + +``` + +## Notes + +- `array:reverse()` reverses member order only; individual members (including multi-item sequence members) are not affected internally. +- An empty array returns an empty array without error. +- For sequence reversal (not arrays), use `reverse()`. + +## See also + +- [array:sort()](../xpath-array-sort) +- [array:subarray()](../xpath-array-subarray) +- [array:head()](../xpath-array-head) +- [array:tail()](../xpath-array-tail) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-size.md b/site/content/xslt/functions/xpath-array-size.md new file mode 100644 index 00000000..3724bfdb --- /dev/null +++ b/site/content/xslt/functions/xpath-array-size.md @@ -0,0 +1,107 @@ +--- +title: "array:size()" +description: "Returns the number of members in an array." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:size(array)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:size()` returns the count of members in an array as an `xs:integer`. An empty array returns `0`. Unlike `count()` which operates on sequences, `array:size()` counts top-level members — each member may itself be a sequence or nested array. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The array whose member count is to be returned. | + +## Return value + +`xs:integer` — the number of top-level members; `0` for an empty array. + +## Examples + +### Checking array size before access + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 3 + 0 + red + +``` + +### Comparing sequence count vs array size + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 3 + 6 + +``` + +## Notes + +- `array:size()` counts top-level members; use `count(array:flatten($arr))` to count all atomic items recursively. +- An array member that is an empty sequence still counts as one member. +- Equivalent to `count(1 to array:size($arr))` but far more efficient. + +## See also + +- [array:get()](../xpath-array-get) +- [array:head()](../xpath-array-head) +- [array:tail()](../xpath-array-tail) +- [array:flatten()](../xpath-array-flatten) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-sort.md b/site/content/xslt/functions/xpath-array-sort.md new file mode 100644 index 00000000..23432114 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-sort.md @@ -0,0 +1,112 @@ +--- +title: "array:sort()" +description: "Returns a new array with members sorted using an optional collation and key function." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:sort(array, collation?, key-function?)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:sort()` returns a new array whose members are in ascending order, determined by the sort key and collation. When no key function is supplied, members are compared directly using the default collation for strings or natural ordering for numbers and other atomic types. When a key function is supplied, it is applied to each member to derive the sort key; members are then sorted by their keys. + +This function is the array equivalent of `sort()` for sequences or `xsl:sort` in templates. It does not modify the input array; it always returns a new one. + +The `collation` argument controls string comparison. The `key-function` takes a single argument (the array member, which is a sequence) and returns an atomic value to use as the sort key. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The input array to sort. | +| `collation` | xs:string? | No | URI of the collation to use for string comparison. Empty sequence uses the default. | +| `key-function` | function(item()*) as xs:anyAtomicType* | No | A function that extracts the sort key from each member. | + +## Return value + +`array(*)` — a new array with the same members in sorted order. + +## Examples + +### Sorting numbers in ascending order + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output:** +``` +1 2 3 5 8 9 +``` + +### Sorting records by a key field + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + + + +``` + +## Notes + +- `array:sort()` always sorts in ascending order. To sort in descending order, reverse the result with `array:reverse()`. +- The collation argument may be `()` (empty sequence) to use the default collation, allowing the key function to be specified without supplying a collation. +- Members that are sequences are compared by their atomized value; members that cannot be compared raise a type error. +- An empty array returns an empty array. + +## See also + +- [array:filter()](../xpath-array-filter) +- [array:for-each()](../xpath-array-for-each) +- [array:reverse()](../xpath-array-reverse) +- [sort()](../xpath-sort) diff --git a/site/content/xslt/functions/xpath-array-subarray.md b/site/content/xslt/functions/xpath-array-subarray.md new file mode 100644 index 00000000..84f5dae2 --- /dev/null +++ b/site/content/xslt/functions/xpath-array-subarray.md @@ -0,0 +1,115 @@ +--- +title: "array:subarray()" +description: "Returns a contiguous sub-array starting at a given position, with optional length." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:subarray(array, start, length?)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:subarray()` extracts a portion of an array. The `start` position is 1-based. If `length` is omitted, all members from `start` to the end are returned. If `length` is 0, an empty array is returned. Out-of-range positions or negative lengths raise `err:FOAY0001`. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The source array. | +| `start` | xs:integer | Yes | The 1-based starting position. | +| `length` | xs:integer? | No | Number of members to include. Defaults to all remaining members. | + +## Return value + +`array(*)` — the specified sub-array. + +## Examples + +### Slicing an array + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + b,c,d + d,e,f + +``` + +### Pagination with subarray + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + +``` + +**Output (page=2, per-page=3):** +```xml + + 4 + 5 + 6 + +``` + +## Notes + +- `array:subarray($arr, 1)` returns a copy of the entire array. +- `array:subarray($arr, 2)` is equivalent to `array:tail($arr)`. +- `start` must be in the range `1` to `array:size($arr) + 1`; `length` must be non-negative. + +## See also + +- [array:get()](../xpath-array-get) +- [array:head()](../xpath-array-head) +- [array:tail()](../xpath-array-tail) +- [array:remove()](../xpath-array-remove) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-array-tail.md b/site/content/xslt/functions/xpath-array-tail.md new file mode 100644 index 00000000..002ae44a --- /dev/null +++ b/site/content/xslt/functions/xpath-array-tail.md @@ -0,0 +1,110 @@ +--- +title: "array:tail()" +description: "Returns a new array containing all members except the first; raises an error if the array is empty." +date: 2026-04-18T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "array function" +syntax: "array:tail(array)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`array:tail()` returns a new array that contains every member of the input array except the first one. If the array has one member, an empty array is returned. If the array is empty, error `err:FOAY0001` is raised. Used together with `array:head()` for recursive array processing. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `array` | array(*) | Yes | The source array. | + +## Return value + +`array(*)` — a new array with the first member removed; empty array if input had one member. + +## Examples + +### Popping the first element in a loop + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + a + 3 + b + +``` + +### Recursive array reverse using head and tail + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 54321 + +``` + +## Notes + +- Equivalent to `array:subarray($array, 2)`. +- Raises `err:FOAY0001` for an empty array; guard with `array:size($arr) gt 0`. +- For efficient list processing, prefer `array:fold-left()` or `array:for-each()` over manual head/tail recursion. + +## See also + +- [array:head()](../xpath-array-head) +- [array:get()](../xpath-array-get) +- [array:subarray()](../xpath-array-subarray) +- [array:size()](../xpath-array-size) +- [xsl:array](../xsl-array) diff --git a/site/content/xslt/functions/xpath-available-environment-variables.md b/site/content/xslt/functions/xpath-available-environment-variables.md new file mode 100644 index 00000000..3e27d63b --- /dev/null +++ b/site/content/xslt/functions/xpath-available-environment-variables.md @@ -0,0 +1,92 @@ +--- +title: "available-environment-variables()" +description: "Returns a sequence of strings naming the environment variables that are available to the processor." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "node function" +syntax: "available-environment-variables()" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`available-environment-variables()` returns a sequence of strings, each being the name of an environment variable that the processor is willing to expose. The order of the returned sequence is implementation-defined. If the processor exposes no environment variables, the function returns the empty sequence. + +This function is used as a companion to `environment-variable()`: first call `available-environment-variables()` to discover what is exposed, then call `environment-variable()` with a specific name to retrieve its value. This pattern avoids relying on the empty-sequence return from `environment-variable()` as the sole indicator of absence. + +The set of available variables may differ between development and production environments. Processors may restrict exposure for security or sandboxing reasons. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:string*` — a sequence of environment variable names that the processor exposes, in implementation-defined order. + +## Examples + +### Listing available variables + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output (varies by environment):** +```xml + + + + + +``` + +### Checking whether a specific variable is exposed + +**Stylesheet:** +```xml + + + + + + + + Mode: + + APP_MODE not available + + + +``` + +**Output:** +``` +APP_MODE not available +``` + +## Notes + +- The result of `available-environment-variables()` may be an empty sequence even when the OS has environment variables set, if the processor has disabled access. +- The function is particularly useful in test harnesses that need to adapt behavior based on the current environment without hard-coding variable names. +- `available-environment-variables()` is a pure function: it has no side effects and returns the same result for repeated calls within a single transformation. +- In Saxon, this function returns all OS-level environment variables by default. Use Saxon's `-feature` flag to restrict access if needed. + +## See also + +- [environment-variable()](../xpath-environment-variable) diff --git a/site/content/xslt/functions/xpath-avg.md b/site/content/xslt/functions/xpath-avg.md new file mode 100644 index 00000000..4fbf95dc --- /dev/null +++ b/site/content/xslt/functions/xpath-avg.md @@ -0,0 +1,118 @@ +--- +title: "avg()" +description: "Returns the arithmetic mean of a sequence of numeric values, or the empty sequence if the input is empty." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "numeric function" +syntax: "avg(sequence)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`avg()` computes the arithmetic mean of all values in a sequence. All items in the sequence must be of a common numeric type (or castable to one). If the sequence is empty, the empty sequence is returned rather than an error. + +Duration types (`xs:yearMonthDuration`, `xs:dayTimeDuration`) are also supported. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | xs:anyAtomicType* | Yes | A sequence of numeric or duration values to average. | + +## Return value + +`xs:anyAtomicType?` — the arithmetic mean of the values, using the promoted common type of the sequence items. Returns the empty sequence when the input is empty. + +## Examples + +### Average of element values + +**Input XML:** +```xml + + + 85 + 92 + 78 + 95 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output:** +```xml + + 87.5 + +``` + +### Average with grouped data + +**Input XML:** +```xml + + + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 125 + 190 + +``` + +## Notes + +- All items in the sequence must be of a compatible numeric type. Mixing `xs:integer` and `xs:string` raises a type error. +- `avg()` is not available in XSLT 1.0. Use `sum() div count()` as a 1.0 equivalent. +- For an empty sequence, the function returns the empty sequence (not `NaN` or zero). + +## See also + +- [abs()](../xpath-abs) +- [min()](../xpath-min) +- [max()](../xpath-max) +- [sum()](../xpath-sum) diff --git a/site/content/xslt/functions/xpath-base-uri.md b/site/content/xslt/functions/xpath-base-uri.md new file mode 100644 index 00000000..1318daf6 --- /dev/null +++ b/site/content/xslt/functions/xpath-base-uri.md @@ -0,0 +1,100 @@ +--- +title: "base-uri()" +description: "Returns the base URI of a node as an xs:anyURI, combining the document's URI with any xml:base attributes in scope." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "base-uri(node?)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`base-uri()` returns the base URI of a node. The base URI is determined by combining the document URI (from where the document was loaded) with any `xml:base` attributes present on ancestor elements. It follows the XML Base specification (RFC 3986 resolution). + +When called without an argument, the context node is used. If the argument is the empty sequence, the empty sequence is returned. If no base URI can be determined, the empty sequence is returned. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `node` | node()? | No | The node whose base URI is requested. Defaults to the context node. | + +## Return value + +`xs:anyURI?` — the base URI of the node, or the empty sequence if no base URI is available. + +## Examples + +### Report base URIs of elements with xml:base + +**Input XML:** +```xml + + + +
Introduction
+
+
+``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output:** +```xml + + http://example.com/docs/ + http://example.com/docs/chapter1/ + http://example.com/docs/chapter1/ + +``` + +### Use base-uri to resolve relative links + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +## Notes + +- If the document was parsed from a string (without a known URI), `base-uri()` may return the empty sequence. +- `base-uri()` is affected by `xml:base` attributes anywhere in the ancestor chain. The effective base URI is the result of resolving each `xml:base` relative to the one above. +- To get the base URI of the stylesheet module itself, use `static-base-uri()`. +- To get the URI of the root document node (ignoring `xml:base`), use `document-uri()`. + +## See also + +- [document-uri()](../xpath-document-uri) +- [static-base-uri()](../xpath-static-base-uri) diff --git a/site/content/xslt/functions/xpath-boolean.md b/site/content/xslt/functions/xpath-boolean.md new file mode 100644 index 00000000..17a0204b --- /dev/null +++ b/site/content/xslt/functions/xpath-boolean.md @@ -0,0 +1,116 @@ +--- +title: "boolean()" +description: "Converts any XPath value — node-set, string, number, or boolean — to a boolean according to XPath 1.0 rules." +date: 2026-04-18T00:00:00Z +version: "1.0" +versionLabel: "XSLT 1.0" +category: "boolean function" +syntax: "boolean(object)" +tags: ["xslt", "reference", "xpath", "xslt1"] +--- + +## Description + +`boolean()` converts its argument to a boolean value following the XPath 1.0 type-conversion rules. The result is always `true` or `false`. + +The conversion rules depend on the type of the argument: + +- **Node-set:** `true` if the node-set is non-empty, `false` otherwise. +- **String:** `true` if the string has a length greater than zero, `false` for the empty string `""`. +- **Number:** `true` if the number is not zero and not `NaN`, `false` for `0` and `NaN`. +- **Boolean:** returned unchanged. + +In practice, most XPath predicates and `xsl:if/@test` expressions perform an implicit boolean conversion, so an explicit call to `boolean()` is needed only when you want to convert a value to a boolean for output or further processing. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `object` | any | Yes | The value to convert. Accepts node-set, string, number, or boolean. | + +## Return value + +`xs:boolean` — `true` or `false` according to the XPath 1.0 boolean conversion rules. + +## Examples + +### Convert a string to boolean + +**Input XML:** +```xml + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + +``` + +**Output:** +```xml + + true + false + +``` + +### Convert a number to boolean + +**Input XML:** +```xml + + + 5 + 0 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + +``` + +**Output:** +```xml + + true + false + +``` + +## Notes + +- An empty node-set, an empty string, the number `0`, and `NaN` all convert to `false`. Everything else converts to `true`. +- Calling `boolean()` explicitly is uncommon inside `xsl:if/@test` because XPath already evaluates the test expression as a boolean. Use it when you need to output the literal string `"true"` or `"false"`. +- `NaN` (produced by operations like `number('abc')`) converts to `false`, not an error. +- In XSLT 2.0+ the `xs:boolean()` constructor and the `fn:boolean()` function behave similarly but operate on sequences; an empty sequence returns `false`. + +## See also + +- [not()](../xpath-not) +- [true()](../xpath-true) +- [false()](../xpath-false) diff --git a/site/content/xslt/functions/xpath-ceiling.md b/site/content/xslt/functions/xpath-ceiling.md new file mode 100644 index 00000000..112a33f4 --- /dev/null +++ b/site/content/xslt/functions/xpath-ceiling.md @@ -0,0 +1,121 @@ +--- +title: "ceiling()" +description: "Returns the smallest integer not less than the argument — equivalent to rounding a number up toward positive infinity." +date: 2026-04-18T00:00:00Z +version: "1.0" +versionLabel: "XSLT 1.0" +category: "numeric function" +syntax: "ceiling(number)" +tags: ["xslt", "reference", "xpath", "xslt1"] +--- + +## Description + +`ceiling()` returns the smallest integer that is greater than or equal to its argument. It rounds a number **up** toward positive infinity. For positive numbers with a fractional part this means adding enough to reach the next integer; for negative numbers it rounds toward zero. + +The argument is first converted to a number using the same rules as `number()`. If the argument is already an integer, it is returned unchanged. Special values (`NaN`, `Infinity`, `-Infinity`) pass through unmodified. + +`ceiling()` is the complement of `floor()`. It is commonly used to compute the total number of pages needed to display a set of items, to round monetary amounts up to the next whole unit, or to ensure allocated space is never less than required. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `number` | xs:double | Yes | The number to round up. | + +## Return value + +`xs:double` — the smallest integer value greater than or equal to the argument. + +## Examples + +### Total pages needed for a list of items + +**Input XML:** +```xml + + + A + B + C + D + E + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 5 + 3 + +``` + +### Ceiling of positive and negative numbers + +**Input XML:** +```xml + + + 3.2 + -3.2 + 4.0 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output:** +```xml + + 4 + -3 + 4 + +``` + +## Notes + +- `ceiling(-3.2)` returns `-3`, not `-4`. The direction is always toward positive infinity. +- If the argument is `NaN`, `ceiling()` returns `NaN`. +- If the argument is `Infinity` or `-Infinity`, the same infinity is returned unchanged. +- Like `floor()`, the return type is `xs:double`, so serialisation may show a trailing `.0` on some processors. +- When dividing integers, use `ceiling($a div $b)` rather than `ceiling($a) div $b`; the latter rounds the numerator first and can produce incorrect results. + +## See also + +- [floor()](../xpath-floor) +- [round()](../xpath-round) +- [number()](../xpath-number) diff --git a/site/content/xslt/functions/xpath-codepoints-to-string.md b/site/content/xslt/functions/xpath-codepoints-to-string.md new file mode 100644 index 00000000..e8023609 --- /dev/null +++ b/site/content/xslt/functions/xpath-codepoints-to-string.md @@ -0,0 +1,120 @@ +--- +title: "codepoints-to-string()" +description: "Constructs a string from a sequence of Unicode codepoint integers, enabling programmatic string assembly from character codes." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "string function" +syntax: "codepoints-to-string(sequence)" +tags: ["xslt", "reference", "xslt2", "xpath"] +--- + +## Description + +`codepoints-to-string()` takes a sequence of integer Unicode codepoints and returns the string formed by the corresponding characters in that order. It is the inverse of `string-to-codepoints()`. + +This function is useful when you need to: +- Construct strings containing characters that are hard to type or embed in XML. +- Build strings programmatically from computed character codes. +- Round-trip through codepoint manipulation (e.g., ROT-13, Caesar cipher). + +If the sequence is empty, the function returns an empty string. An error is raised if any integer in the sequence is not a valid XML character codepoint (e.g., codepoints in the surrogate range U+D800–U+DFFF). + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | xs:integer* | Yes | A sequence of Unicode codepoint integers. | + +## Return value + +`xs:string` — the string formed by concatenating the characters for each codepoint in order. + +## Examples + +### Building a string from codepoints + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Hello + + © + +``` + +### Applying a simple character shift (Caesar cipher) + +**Input XML:** +```xml + + + Hello + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Uryyb + +``` + +## Notes + +- Codepoints must be valid XML characters. Codepoints 0 (except in some contexts), and the range U+D800–U+DFFF (surrogates) are not valid and will cause a dynamic error. +- The function accepts a single integer or a sequence of integers interchangeably. +- Combining with `string-to-codepoints()` enables low-level string transformations without regular expressions. +- Codepoint 32 is a space, 10 is a newline (` `), 9 is a tab (` `). + +## See also + +- [string-to-codepoints()](../xpath-string-to-codepoints) +- [normalize-unicode()](../xpath-normalize-unicode) +- [compare()](../xpath-compare) diff --git a/site/content/xslt/functions/xpath-collection.md b/site/content/xslt/functions/xpath-collection.md new file mode 100644 index 00000000..e0e4c7fa --- /dev/null +++ b/site/content/xslt/functions/xpath-collection.md @@ -0,0 +1,94 @@ +--- +title: "collection()" +description: "Returns a sequence of nodes from a named collection, enabling batch processing of multiple XML documents." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "collection(uri?)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`collection()` returns a sequence of nodes from a **collection** identified by a URI. A collection is a processor-defined set of nodes — typically a set of XML documents. The most common use in Saxon is to pass a directory URI, which the processor expands to all XML files in that directory. + +When called without an argument (or with the empty sequence), the **default collection** is returned. The default collection may be set programmatically via the processor's API. + +The exact semantics of the URI are implementation-defined. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `uri` | xs:string? | No | URI identifying the collection. Omit or pass the empty sequence for the default collection. | + +## Return value + +`node()*` — a sequence of nodes from the collection, typically document nodes. + +## Examples + +### Process all XML files in a directory (Saxon) + +**Stylesheet:** +```xml + + + + + + + + + <xsl:value-of select="*/title"/> + + + + + +``` + +**Output (example with two files):** +```xml + + + Learning XSLT + + + XPath in Practice + + +``` + +### Merge elements from all collected documents + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +## Notes + +- The URI syntax for directory collections is Saxon-specific: `file:///path/?select=*.xml` selects XML files; `recurse=yes` enables recursive directory traversal. +- Saxon also supports catalog-style collection documents (an XML file listing URIs). +- The order of nodes in the returned sequence is implementation-defined. +- For a sequence of URIs rather than document nodes, use `uri-collection()`. + +## See also + +- [uri-collection()](../xpath-uri-collection) +- [document-uri()](../xpath-document-uri) diff --git a/site/content/xslt/functions/xpath-compare.md b/site/content/xslt/functions/xpath-compare.md new file mode 100644 index 00000000..8023f673 --- /dev/null +++ b/site/content/xslt/functions/xpath-compare.md @@ -0,0 +1,130 @@ +--- +title: "compare()" +description: "Compares two strings using a collation and returns -1, 0, or 1 indicating their relative order." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "string function" +syntax: "compare(string1, string2, collation?)" +tags: ["xslt", "reference", "xslt2", "xpath"] +--- + +## Description + +`compare()` performs a three-way comparison of two strings, returning: + +- `-1` if `string1` sorts before `string2` +- `0` if they are equal +- `1` if `string1` sorts after `string2` + +Without a `collation` argument, the default collation (Unicode codepoint order) is used. With a collation URI, language- and locale-sensitive ordering is applied — for example, treating accented and unaccented letters as equivalent, or following locale-specific alphabetical order. + +This is the XPath 2.0 equivalent of the three-way comparison operators found in languages like Java (`compareTo`) or C (`strcmp`), and it is the correct function to use when you need ordered comparison rather than just equality. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `string1` | xs:string? | Yes | The first string. | +| `string2` | xs:string? | Yes | The second string. | +| `collation` | xs:string | No | A collation URI. Defaults to the default collation (typically Unicode codepoint). | + +If either argument is an empty sequence, the function returns an empty sequence. + +## Return value + +`xs:integer?` — `-1`, `0`, or `1`, or the empty sequence if either argument is empty. + +## Examples + +### Sorting strings and finding the alphabetically first + +**Input XML:** +```xml + + + banana + apple + cherry + date + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml +apple + + -1 + 1 + 0 + +``` + +### Custom sort using compare() in a function + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml +pear +``` + +## Notes + +- For simple equality testing, use `=` or `eq`. `compare()` is most useful when you need the direction of the difference, not just whether strings are equal. +- Codepoint collation compares characters by Unicode code number, which does not always match alphabetical order in all languages. +- Saxon supports IETF BCP 47 language tags as collation URIs (e.g., `http://saxon.sf.net/collation?lang=fr` for French). +- `compare($a, $b) = 0` is equivalent to `$a = $b` under the same collation. + +## See also + +- [upper-case()](../xpath-upper-case) +- [lower-case()](../xpath-lower-case) +- [codepoints-to-string()](../xpath-codepoints-to-string) +- [deep-equal()](../xpath-deep-equal) diff --git a/site/content/xslt/functions/xpath-copy-of.md b/site/content/xslt/functions/xpath-copy-of.md new file mode 100644 index 00000000..0c828795 --- /dev/null +++ b/site/content/xslt/functions/xpath-copy-of.md @@ -0,0 +1,110 @@ +--- +title: "copy-of()" +description: "Returns a deep copy of all nodes in the sequence, detached from the original document." +date: 2026-04-19T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "copy-of(sequence)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`copy-of()` returns a deep copy of each node in the sequence. The copies are new nodes that are not part of any existing document tree — they are detached roots. Modifications to the original nodes do not affect the copies, and the copies share no identity with their originals. + +This function is the XPath 2.0 function counterpart to the `xsl:copy-of` instruction. It is especially useful inside XPath expressions where you need to pass a fresh copy of a subtree to a function, store it in a variable, or use it as a constructor argument. + +Atomic values in the sequence are returned as-is; only node items are copied. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | item()* | Yes | The nodes (and atomic values) to copy. | + +## Return value + +`item()*` — deep copies of any node items in the sequence; atomic values returned unchanged. + +## Examples + +### Storing a copy in a variable + +**Input XML:** +```xml + + + XSLT 2.0Kay + XPathMangano + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + +``` + +**Output:** +```xml + + XSLT 2.0Kay + XPathMangano + +``` + +### Passing a copy to a function + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + XSLT 2.0Kay + +``` + +## Notes + +- `copy-of()` creates parentless copies; the copies have no document-node parent and no sibling nodes. +- The function copies all descendants, attributes, namespace nodes, and text content recursively. +- It differs from `xsl:copy-of` (the instruction) in that it can be used inline in an XPath expression rather than as a standalone instruction. +- In XSLT 3.0, `snapshot()` serves a similar purpose for streaming contexts where nodes may not be available after the streaming pass ends. + +## See also + +- [snapshot()](../xpath-snapshot) +- [deep-equal()](../xpath-deep-equal) +- [xsl:copy-of](../xsl-copy-of) diff --git a/site/content/xslt/functions/xpath-current-date-time.md b/site/content/xslt/functions/xpath-current-date-time.md new file mode 100644 index 00000000..97726d73 --- /dev/null +++ b/site/content/xslt/functions/xpath-current-date-time.md @@ -0,0 +1,94 @@ +--- +title: "current-dateTime()" +description: "Returns the current date and time as an xs:dateTime value, fixed for the duration of the transformation." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "date function" +syntax: "current-dateTime()" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`current-dateTime()` returns the current date and time as a single `xs:dateTime` value, including the implicit timezone of the processor. The value is **fixed** for the entire transformation, so all calls within a single run return the same timestamp. + +It is the most complete timestamp function in XPath 2.0, combining both the date information of `current-date()` and the time information of `current-time()`. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:dateTime` — the current date and time in ISO 8601 form `YYYY-MM-DDTHH:MM:SS.sss+HH:MM`. Stable for the lifetime of the transformation. + +## Examples + +### Add a full ISO timestamp to the root element + +**Input XML:** +```xml + + + Alpha + Beta + +``` + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output (example):** +```xml + + Alpha + Beta + +``` + +### Format a human-readable timestamp + +**Stylesheet:** +```xml + + + + + + + + +``` + +**Output (example):** +``` +Saturday 18 April 2026 at 14:32 +``` + +## Notes + +- Not available in XSLT 1.0. +- All three functions — `current-date()`, `current-time()`, and `current-dateTime()` — return consistent values derived from the same instant. +- Use `xs:date(current-dateTime())` to extract just the date portion, or `xs:time(current-dateTime())` for just the time. +- Pair with `format-dateTime()` to produce locale-aware output. + +## See also + +- [current-date()](../xpath-current-date) +- [current-time()](../xpath-current-time) +- [format-dateTime()](../xpath-format-date-time) +- [format-date()](../xpath-format-date) diff --git a/site/content/xslt/functions/xpath-current-date.md b/site/content/xslt/functions/xpath-current-date.md new file mode 100644 index 00000000..7f1ab217 --- /dev/null +++ b/site/content/xslt/functions/xpath-current-date.md @@ -0,0 +1,96 @@ +--- +title: "current-date()" +description: "Returns the current date as an xs:date value, stable for the duration of the transformation." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "date function" +syntax: "current-date()" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`current-date()` returns today's date as an `xs:date` value. The returned value includes the implicit timezone of the processor. Crucially, the value is **fixed** for the entire transformation: all calls within one transformation return the same date, ensuring consistency across the output. + +This is the typed-value counterpart to calling `substring-before(string(current-dateTime()), 'T')` in XSLT 1.0. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:date` — the current date in the form `YYYY-MM-DD+HH:MM` (with timezone offset). The date is stable for the lifetime of the transformation. + +## Examples + +### Stamp a document with today's date + +**Input XML:** +```xml + + + Annual Summary + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + +``` + +**Output (example):** +```xml + + 2026-04-18+01:00 + Annual Summary + +``` + +### Format today's date for display + +**Stylesheet:** +```xml + + + + + + + + +``` + +**Output (example):** +``` +Saturday, 18 April 2026 +``` + +## Notes + +- `current-date()` is not available in XSLT 1.0. +- The value includes the processor's implicit timezone. Use `adjust-date-to-timezone()` to convert to a different offset. +- To extract parts of the date, use `year-from-date()`, `month-from-date()`, or `day-from-date()`. +- For a combined date and time, use `current-dateTime()`. + +## See also + +- [current-time()](../xpath-current-time) +- [current-dateTime()](../xpath-current-date-time) +- [year-from-date()](../xpath-year-from-date) +- [month-from-date()](../xpath-month-from-date) +- [day-from-date()](../xpath-day-from-date) +- [format-date()](../xpath-format-date) diff --git a/site/content/xslt/functions/xpath-current-group.md b/site/content/xslt/functions/xpath-current-group.md new file mode 100644 index 00000000..b821d4d8 --- /dev/null +++ b/site/content/xslt/functions/xpath-current-group.md @@ -0,0 +1,102 @@ +--- +title: "current-group()" +description: "Returns the sequence of items in the current group inside an xsl:for-each-group instruction." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "current-group()" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`current-group()` returns all the items that belong to the current group within an `` instruction. It is only meaningful inside `xsl:for-each-group` — outside that instruction, the result is implementation-defined (typically the empty sequence). + +Paired with `current-grouping-key()`, it gives you full access to both the grouping criterion and the grouped items. + +## Parameters + +This function takes no parameters. + +## Return value + +`item()*` — the sequence of items in the current group. + +## Examples + +### Summarise sales by region + +**Input XML:** +```xml + + + + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + 2250 + 2380 + 1300 + +``` + +### Wrap each group in a container element + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +## Notes + +- `current-group()` is only valid inside `xsl:for-each-group`. Using it elsewhere is an error or returns the empty sequence depending on the processor. +- The items in `current-group()` are a subset of the `select` expression of the enclosing `xsl:for-each-group`, in document order. +- The context item inside `xsl:for-each-group` is the **first item** of the current group; `current-group()` gives you all items. + +## See also + +- [current-grouping-key()](../xpath-current-grouping-key) +- [xsl:for-each-group](../xsl-for-each-group) diff --git a/site/content/xslt/functions/xpath-current-grouping-key.md b/site/content/xslt/functions/xpath-current-grouping-key.md new file mode 100644 index 00000000..6d7bd775 --- /dev/null +++ b/site/content/xslt/functions/xpath-current-grouping-key.md @@ -0,0 +1,110 @@ +--- +title: "current-grouping-key()" +description: "Returns the grouping key of the current group inside an xsl:for-each-group instruction." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "current-grouping-key()" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`current-grouping-key()` returns the value of the grouping key for the current group within an `` instruction. The type and value of the key corresponds to the result of evaluating the `group-by`, `group-adjacent`, `group-starting-with`, or `group-ending-with` attribute for the representative item of the current group. + +It is only meaningful inside `xsl:for-each-group`. Outside that instruction, the result is implementation-defined. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:anyAtomicType?` — the grouping key of the current group, or the empty sequence when used with `group-starting-with` or `group-ending-with`. + +## Examples + +### Group and label by category + +**Input XML:** +```xml + + + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + XSLT Guide + XML Handbook + + + Tablet + Laptop + + +``` + +### Use the grouping key in a heading + +**Stylesheet:** +```xml + + + + + + + +

+
    + +
  • +
    +
+
+ +
+
+``` + +## Notes + +- For `group-starting-with` and `group-ending-with`, `current-grouping-key()` returns the empty sequence because these grouping methods do not use a key expression. +- `current-grouping-key()` is only valid inside `xsl:for-each-group`. Using it elsewhere is an error. +- When multiple keys are produced by a sequence-valued `group-by`, the key for the current group is the specific value that identified this group. + +## See also + +- [current-group()](../xpath-current-group) +- [xsl:for-each-group](../xsl-for-each-group) diff --git a/site/content/xslt/functions/xpath-current-merge-group.md b/site/content/xslt/functions/xpath-current-merge-group.md new file mode 100644 index 00000000..3dfa108a --- /dev/null +++ b/site/content/xslt/functions/xpath-current-merge-group.md @@ -0,0 +1,117 @@ +--- +title: "current-merge-group()" +description: "Returns the sequence of items in the current merge group inside an xsl:merge-action block." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "node function" +syntax: "current-merge-group(source?)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`current-merge-group()` is used inside the `xsl:merge-action` child of an `xsl:merge` instruction. It returns the sequence of items from the current merge group — that is, all items from one or more merge sources that share the same current merge key. + +When `xsl:merge` processes multiple input streams simultaneously, it groups corresponding items by their computed merge key. Inside `xsl:merge-action`, `current-merge-group()` without an argument returns all items from all sources in the current group. When a `source` argument is supplied (the value of a `for-each-source` attribute or a source name), the function returns items only from that specific merge source. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `source` | xs:string | No | The name of the merge source to restrict the group to. Omit to get items from all sources. | + +## Return value + +`item()*` — the items in the current merge group, optionally restricted to a named source. + +## Examples + +### Merging two sorted lists + +**Input XML (file1.xml):** +```xml + + + Alpha from source1 + Beta from source1 + +``` + +**Input XML (file2.xml):** +```xml + + + Alpha from source2 + Gamma from source2 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + Alpha from source1 + Alpha from source2 + + + Beta from source1 + + + Gamma from source2 + + +``` + +### Reading from a specific source + +**Stylesheet snippet:** +```xml + + + + + + +``` + +## Notes + +- `current-merge-group()` is only valid inside the `xsl:merge-action` element; using it elsewhere raises a static error. +- Without an argument, it returns items from all named merge sources combined. +- The merge sources must provide pre-sorted input or declare sort keys via `xsl:merge-key` for `xsl:merge` to operate correctly. +- `current-merge-group()` and `current-merge-key()` are the two functions designed specifically for use inside `xsl:merge-action`. + +## See also + +- [current-merge-key()](../xpath-current-merge-key) +- [xsl:use-accumulators](../xsl-use-accumulators) diff --git a/site/content/xslt/functions/xpath-current-merge-key.md b/site/content/xslt/functions/xpath-current-merge-key.md new file mode 100644 index 00000000..0aa06d3c --- /dev/null +++ b/site/content/xslt/functions/xpath-current-merge-key.md @@ -0,0 +1,123 @@ +--- +title: "current-merge-key()" +description: "Returns the current merge key value inside an xsl:merge-action block." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "node function" +syntax: "current-merge-key()" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`current-merge-key()` returns the value of the merge key for the current group being processed inside an `xsl:merge-action` block. When `xsl:merge` groups items from one or more sources by their computed key, `current-merge-key()` provides the key value shared by all items in the current group. + +The returned value is an atomic value or a sequence of atomic values corresponding to the `xsl:merge-key` expressions declared in the merge sources. When multiple keys are declared (composite keys), the function returns a sequence of values — one per key component — in declaration order. + +`current-merge-key()` is the merge equivalent of `current-grouping-key()` from `xsl:for-each-group`. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:anyAtomicType+` — the merge key value(s) for the current group. + +## Examples + +### Displaying the merge key in output + +**Input XML (employees.xml):** +```xml + + + + + + +``` + +**Input XML (salaries.xml):** +```xml + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + + + + + + + + + +``` + +### Using the key in a conditional + +**Stylesheet snippet:** +```xml + + + + + + + +``` + +## Notes + +- `current-merge-key()` is only valid inside the `xsl:merge-action` element. +- For composite merge keys (multiple `xsl:merge-key` declarations), the function returns a sequence of atomic values in declaration order. +- The key type is determined by the key expression; string, numeric, date, and other atomic types are all supported. +- This function is the merge counterpart to `current-grouping-key()` used with `xsl:for-each-group`. + +## See also + +- [current-merge-group()](../xpath-current-merge-group) +- [xsl:use-accumulators](../xsl-use-accumulators) diff --git a/site/content/xslt/functions/xpath-current-output-uri.md b/site/content/xslt/functions/xpath-current-output-uri.md new file mode 100644 index 00000000..8ce8ff1c --- /dev/null +++ b/site/content/xslt/functions/xpath-current-output-uri.md @@ -0,0 +1,97 @@ +--- +title: "current-output-uri()" +description: "Returns the URI of the current result document being written inside an xsl:result-document instruction." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "current-output-uri()" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`current-output-uri()` returns the URI of the result document currently being written — the `href` value of the enclosing `` instruction. Outside an `xsl:result-document`, it returns the empty sequence. + +This is useful for embedding a document's own URI as metadata within itself, logging which file is being generated, or constructing relative cross-references between generated documents. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:anyURI?` — the URI of the current result document, or the empty sequence when called outside `xsl:result-document`. + +## Examples + +### Embed the output URI in each generated document + +**Input XML:** +```xml + + + + + +``` + +**Stylesheet:** +```xml + + + + + + + + + <xsl:value-of select="@title"/> + + + + + +``` + +**Output (ch1.xml):** +```xml + + Introduction + +``` + +### Log generated file names to the principal output + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +## Notes + +- Returns the empty sequence when called in the principal result tree (outside any `xsl:result-document`). +- The returned URI is the value of the `href` attribute of the enclosing `xsl:result-document`, resolved against the static base URI if it is relative. +- Useful for generating self-referential metadata in split-document outputs. + +## See also + +- [static-base-uri()](../xpath-static-base-uri) +- [document-uri()](../xpath-document-uri) diff --git a/site/content/xslt/functions/xpath-current-time.md b/site/content/xslt/functions/xpath-current-time.md new file mode 100644 index 00000000..70d0ab23 --- /dev/null +++ b/site/content/xslt/functions/xpath-current-time.md @@ -0,0 +1,94 @@ +--- +title: "current-time()" +description: "Returns the current time as an xs:time value, stable and fixed for the duration of the transformation." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "date function" +syntax: "current-time()" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`current-time()` returns the current time as an `xs:time` value, including the implicit timezone of the processor. Like `current-date()` and `current-dateTime()`, the value is **fixed** for the entire transformation: repeated calls return the same time, guaranteeing a consistent timestamp throughout the output. + +## Parameters + +This function takes no parameters. + +## Return value + +`xs:time` — the current time in the form `HH:MM:SS.sss+HH:MM` (with timezone offset). Stable for the lifetime of the transformation. + +## Examples + +### Embed the generation time in output + +**Input XML:** +```xml + + + First item + Second item + +``` + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output (example):** +```xml + + First item + Second item + +``` + +### Format the current time for display + +**Stylesheet:** +```xml + + + + + + + + +``` + +**Output (example):** +``` +14:32:07 +``` + +## Notes + +- Not available in XSLT 1.0. +- The value includes the processor's implicit timezone. Pair with `adjust-time-to-timezone()` to normalise to UTC or another offset. +- To extract individual components, use `hours-from-time()`, `minutes-from-time()`, or `seconds-from-time()`. +- For a combined date and time, use `current-dateTime()`. + +## See also + +- [current-date()](../xpath-current-date) +- [current-dateTime()](../xpath-current-date-time) +- [hours-from-time()](../xpath-hours-from-time) +- [minutes-from-time()](../xpath-minutes-from-time) +- [seconds-from-time()](../xpath-seconds-from-time) +- [format-time()](../xpath-format-time) diff --git a/site/content/xslt/functions/xpath-day-from-date.md b/site/content/xslt/functions/xpath-day-from-date.md new file mode 100644 index 00000000..ecc5a8e8 --- /dev/null +++ b/site/content/xslt/functions/xpath-day-from-date.md @@ -0,0 +1,105 @@ +--- +title: "day-from-date()" +description: "Extracts the day-of-month component from an xs:date value as an xs:integer in the range 1–31." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "date function" +syntax: "day-from-date(date)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`day-from-date()` returns the day-of-month component of an `xs:date` value as an `xs:integer` between 1 and 31. If the argument is the empty sequence, the empty sequence is returned. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `date` | xs:date? | Yes | The date value from which to extract the day. | + +## Return value + +`xs:integer?` — integer from 1 to 31 representing the day of the month, or the empty sequence if the argument is the empty sequence. + +## Examples + +### Display a formatted date with separate components + +**Input XML:** +```xml + + + 2026-04-18 + 2026-05-18 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + 18 + 4 + 2026 + + + 18 + 5 + 2026 + + +``` + +### Find events on the 1st of any month + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +## Notes + +- The argument must be typed as `xs:date`. Cast string values with `xs:date(.)` or `xs:date(@attr)`. +- Returns 1–31 depending on the month; it does not validate whether the day is valid for the given month (that is enforced when constructing the `xs:date` value). +- For `xs:dateTime` values, use `day-from-dateTime()`. + +## See also + +- [year-from-date()](../xpath-year-from-date) +- [month-from-date()](../xpath-month-from-date) +- [current-date()](../xpath-current-date) diff --git a/site/content/xslt/functions/xpath-deep-equal.md b/site/content/xslt/functions/xpath-deep-equal.md new file mode 100644 index 00000000..5c7e5308 --- /dev/null +++ b/site/content/xslt/functions/xpath-deep-equal.md @@ -0,0 +1,107 @@ +--- +title: "deep-equal()" +description: "Returns true if two sequences are deeply equal: same items in the same order with equal node identity or atomic values." +date: 2026-04-19T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "sequence function" +syntax: "deep-equal(sequence1, sequence2, collation?)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`deep-equal()` compares two sequences item by item. Two sequences are deeply equal if they have the same length and each pair of corresponding items is deeply equal. For atomic values, deep equality uses the same comparison as `=` with type promotion. For nodes, deep equality means the nodes have the same kind, name, and — recursively — the same children, attributes, and text content. + +The optional `collation` argument controls string comparison. When omitted, the default collation is used. This makes `deep-equal()` suitable for locale-aware comparisons of mixed sequences containing strings. + +`deep-equal()` never raises an error for incompatible types: comparing an integer to a string returns `false` rather than a type error, which distinguishes it from the `=` operator. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence1` | item()* | Yes | The first sequence to compare. | +| `sequence2` | item()* | Yes | The second sequence to compare. | +| `collation` | xs:string | No | URI of the collation used for string comparison. | + +## Return value + +`xs:boolean` — `true` if the sequences are deeply equal, `false` otherwise. + +## Examples + +### Comparing two element subtrees + +**Input XML:** +```xml + + + 12 + 12 + 13 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + +``` + +**Output:** +```xml + + true + false + +``` + +### Comparing sequences of atomic values + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output:** +``` +true +false +``` + +## Notes + +- `deep-equal()` compares attributes regardless of document order for element nodes. Two elements with the same attributes in a different order are still deeply equal. +- Namespace nodes, processing instructions, and comments are included in the comparison when they are present in the node's children. +- The function is particularly useful in unit tests and validation stylesheets where you need to assert that a transformation produced an expected XML structure. +- An empty sequence is deeply equal only to another empty sequence. + +## See also + +- [empty()](../xpath-empty) +- [count()](../xpath-count) +- [exactly-one()](../xpath-exactly-one) diff --git a/site/content/xslt/functions/xpath-distinct-values.md b/site/content/xslt/functions/xpath-distinct-values.md new file mode 100644 index 00000000..829da72c --- /dev/null +++ b/site/content/xslt/functions/xpath-distinct-values.md @@ -0,0 +1,130 @@ +--- +title: "distinct-values()" +description: "Returns a sequence containing only the distinct values from the input sequence, removing duplicates using value equality." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "sequence function" +syntax: "distinct-values(sequence, collation?)" +tags: ["xslt", "reference", "xslt2", "xpath"] +--- + +## Description + +`distinct-values()` removes duplicate atomic values from a sequence, retaining one representative from each group of equal values. The order of retained values follows the order of first occurrence in the input sequence. + +Equality is determined by value semantics (not identity): for strings, the default Unicode codepoint collation is used unless a different `collation` URI is provided; for numeric types, numeric equality applies (so `1` and `1.0` are equal). + +The function works on atomic values only. If the input contains nodes, their typed values (strings) are compared — not the nodes themselves. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | xs:anyAtomicType* | Yes | The sequence to deduplicate. | +| `collation` | xs:string | No | A collation URI for string comparison. | + +## Return value + +`xs:anyAtomicType*` — the sequence with duplicates removed, preserving first-occurrence order. + +## Examples + +### Getting unique categories + +**Input XML:** +```xml + + + Apple + Carrot + Banana + Rice + Broccoli + Cherry + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Fruit + Grain + Vegetable + +``` + +### Counting unique authors across articles + +**Input XML:** +```xml + + +
Article 1
+
Article 2
+
Article 3
+
Article 4
+
Article 5
+
+``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + + Alice + Bob + Carol + + +``` + +## Notes + +- `distinct-values()` operates on atomic values, not nodes. If you apply it to element nodes, their string values are compared. If you need to group and deduplicate by element identity, use `xsl:for-each-group` with `group-by`. +- For grouping with the ability to access all members of each group, `xsl:for-each-group` is more appropriate than `distinct-values()`. +- Numeric type coercion applies: `distinct-values((1, 1.0, 1e0))` may return just one item, since all are numerically equal. +- The order of results is the order of first occurrence — it is not sorted. Add `xsl:sort` or `sort()` to sort the output. + +## See also + +- [xsl:for-each-group](../xsl-for-each-group) +- [index-of()](../xpath-index-of) +- [count()](../xpath-count) diff --git a/site/content/xslt/functions/xpath-document-uri.md b/site/content/xslt/functions/xpath-document-uri.md new file mode 100644 index 00000000..6352bb41 --- /dev/null +++ b/site/content/xslt/functions/xpath-document-uri.md @@ -0,0 +1,86 @@ +--- +title: "document-uri()" +description: "Returns the URI of the document node that contains the given node, as an xs:anyURI." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "document-uri(node?)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`document-uri()` returns the URI used to load the document containing the given node. Unlike `base-uri()`, it returns the URI of the **document node** itself and is not affected by `xml:base` attributes on descendant elements. + +When called without an argument, the context node is used. If the argument is the empty sequence or the node has no document URI (e.g., it was constructed in memory), the empty sequence is returned. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `node` | node()? | No | The node whose document URI is requested. Defaults to the context node. | + +## Return value + +`xs:anyURI?` — the URI of the document node, or the empty sequence if no URI is available. + +## Examples + +### Report the document URI of a loaded document + +**Stylesheet:** +```xml + + + + + + + + + + +``` + +**Output (example):** +```xml + + file:///data/input.xml + +``` + +### Load and track multiple documents + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +## Notes + +- `document-uri()` returns the URI of the **document root**, not an element's base URI. For the effective base URI (considering `xml:base`), use `base-uri()`. +- For nodes created via `parse-xml()` or result tree fragments, the document URI is typically absent (empty sequence). +- The function was introduced in XPath 2.0 and is not available in XSLT 1.0. + +## See also + +- [base-uri()](../xpath-base-uri) +- [static-base-uri()](../xpath-static-base-uri) +- [parse-xml()](../xpath-parse-xml) diff --git a/site/content/xslt/functions/xpath-document.md b/site/content/xslt/functions/xpath-document.md new file mode 100644 index 00000000..ff091b58 --- /dev/null +++ b/site/content/xslt/functions/xpath-document.md @@ -0,0 +1,126 @@ +--- +title: "document()" +description: "Loads an external XML document by URI and returns its root node as a node-set, enabling multi-document transformations in XSLT 1.0." +date: 2026-04-18T00:00:00Z +version: "1.0" +versionLabel: "XSLT 1.0" +category: "node function" +syntax: "document(uri, node?)" +tags: ["xslt", "reference", "xpath", "xslt1"] +--- + +## Description + +`document()` retrieves an external XML document and returns it as a node-set containing the document root. This is the primary mechanism in XSLT 1.0 for accessing data from multiple sources within a single transformation. + +The first argument can be: +- A **string** URI — the document at that URI is loaded and returned as a single-item node-set. +- A **node-set** — each node is converted to its string value (treated as a URI), the corresponding documents are loaded, and their root nodes are returned as a combined node-set. + +The optional second argument is a node from which the base URI for resolving relative URIs is taken. If omitted, relative URIs are resolved against the base URI of the stylesheet. + +Calling `document('')` is a special idiom: it returns the root of the **stylesheet document itself**, allowing stylesheet data to be embedded as XML and accessed from templates. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `uri` | xs:string or node-set | Yes | URI of the external document, or a node-set of URI-valued nodes. | +| `node` | node-set | No | Node whose base URI is used to resolve relative URIs in the first argument. | + +## Return value + +`node-set` — the root nodes of the loaded document(s). + +## Examples + +### Load an external lookup document + +**External file: `colors.xml`** +```xml + + + Red + Green + Blue + +``` + +**Input XML:** +```xml + + + Apple + Leaf + Sky + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Apple + Leaf + Sky + +``` + +### Embed data in the stylesheet using document('') + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + + + + + + + +``` + +## Notes + +- The behavior when the referenced document cannot be found is processor-specific: some processors raise a fatal error, others return an empty node-set. Check processor documentation. +- `document('')` returns the stylesheet document; combine with an XPath expression to navigate to embedded data elements. +- Relative URIs are resolved against the **stylesheet** base URI by default, not the source document URI. Use the second argument to change the base. +- In XSLT 2.0+, `document()` is superseded by the `fn:doc()` and `fn:collection()` functions, which integrate with XPath 2.0's type system. + +## See also + +- [xsl:import](../xsl-import) +- [xsl:include](../xsl-include) diff --git a/site/content/xslt/functions/xpath-element-available.md b/site/content/xslt/functions/xpath-element-available.md new file mode 100644 index 00000000..22aeb983 --- /dev/null +++ b/site/content/xslt/functions/xpath-element-available.md @@ -0,0 +1,106 @@ +--- +title: "element-available()" +description: "Returns true if the named XSLT instruction or extension element is supported by the processor, enabling portable fallback branches." +date: 2026-04-18T00:00:00Z +version: "1.0" +versionLabel: "XSLT 1.0" +category: "node function" +syntax: "element-available(name)" +tags: ["xslt", "reference", "xpath", "xslt1"] +--- + +## Description + +`element-available()` tests whether the XSLT processor supports a named instruction element and returns a boolean. The argument is a string containing a QName; if the QName is in the `xsl:` namespace, it tests for a standard XSLT instruction. If it is in another namespace, it tests for a processor-specific extension element. + +The function is intended for use inside `xsl:choose`/`xsl:when` or `xsl:if` to branch between implementations depending on what the current processor supports. Combined with `xsl:fallback`, it provides a portable way to use extension elements with graceful degradation. + +Only elements that appear as **children of the stylesheet** (i.e. XSLT instructions and extension elements, not result elements) are tested. Testing for an arbitrary user-defined element name that is not an instruction always returns `false`. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `name` | xs:string | Yes | A QName string naming the element to test. The namespace prefix must be in scope. | + +## Return value + +`xs:boolean` — `true` if the element is available, `false` otherwise. + +## Examples + +### Test for a standard XSLT instruction + +**Input XML:** +```xml + +AB +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + true + false + +``` + +### Guard use of an extension element + +**Stylesheet:** +```xml + + + + + + + + + + + Multi-document output supported. + + + Multi-document output not supported; writing single file. + + + + + +``` + +## Notes + +- `element-available()` only tests **XSLT instructions** and **extension elements**. It does not test for result element names (elements in no namespace or a non-XSLT namespace that become part of the output tree). +- The prefix in the QName string must be declared in the stylesheet's namespace context; otherwise the function raises an error. +- Standard XSLT 1.0 instructions (e.g. `xsl:for-each`, `xsl:if`, `xsl:choose`) always return `true` in a conformant XSLT 1.0 processor. +- In XSLT 2.0+, the function is unchanged. It can be used to test for XSLT 2.0 instructions (e.g. `xsl:for-each-group`) when running under a processor that may be in XSLT 1.0 compatibility mode. + +## See also + +- [function-available()](../xpath-function-available) +- [system-property()](../xpath-system-property) +- [xsl:fallback](../xsl-fallback) diff --git a/site/content/xslt/functions/xpath-empty.md b/site/content/xslt/functions/xpath-empty.md new file mode 100644 index 00000000..160f3cfe --- /dev/null +++ b/site/content/xslt/functions/xpath-empty.md @@ -0,0 +1,107 @@ +--- +title: "empty()" +description: "Returns true if the sequence has zero items, and false if it contains one or more items." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "sequence function" +syntax: "empty(sequence)" +tags: ["xslt", "reference", "xslt2", "xpath"] +--- + +## Description + +`empty()` tests whether a sequence contains no items. It is the logical complement of `exists()`: `empty($s)` is equivalent to `not(exists($s))` and to `count($s) = 0`, but is more readable and may be more efficient because the processor can stop as soon as it finds any item. + +The sequence argument may be any XPath expression — a node selection, a function result, or a constructed sequence. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | item()* | Yes | The sequence to test. | + +## Return value + +`xs:boolean` — `true` if the sequence is empty, `false` otherwise. + +## Examples + +### Checking for missing child elements + +**Input XML:** +```xml + + + Alphaxml + Beta + Gamma + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Alpha + Beta + Gamma + +``` + +### Providing a default when a sequence is empty + +**Stylesheet:** +```xml + + + + + + + + + + No active items found. + + + + + + + + + + +``` + +## Notes + +- `empty($seq)` is semantically equivalent to `not($seq)` for sequences, but is preferred for clarity when working with typed sequences. +- For node selections, `empty(//foo)` is more readable than `not(//foo)`, especially in predicate contexts. +- `empty()` short-circuits: it does not need to evaluate the entire sequence; it stops at the first item. +- Use `exists()` to test the positive case; avoid double negation with `not(empty(...))`. + +## See also + +- [exists()](../xpath-exists) +- [count()](../xpath-count) +- [zero-or-one()](../xpath-zero-or-one) diff --git a/site/content/xslt/functions/xpath-ends-with.md b/site/content/xslt/functions/xpath-ends-with.md new file mode 100644 index 00000000..449a6995 --- /dev/null +++ b/site/content/xslt/functions/xpath-ends-with.md @@ -0,0 +1,102 @@ +--- +title: "ends-with()" +description: "Returns true if the first string ends with the second string, using optional collation for comparison." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "string function" +syntax: "ends-with(string, suffix)" +tags: ["xslt", "reference", "xslt2", "xpath"] +--- + +## Description + +`ends-with()` tests whether the string in the first argument ends with the string in the second argument. It returns `true` if the suffix matches, `false` otherwise. + +The comparison uses codepoint-by-codepoint equality by default (same as XPath's `=` operator on strings). In XPath 2.0 a third `collation` argument is allowed for locale-sensitive suffix testing, though most processors default to the Unicode codepoint collation. + +If either argument is an empty string `""`, special rules apply: any string ends with `""` (always `true`), and `""` ends with `""` (also `true`). + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `string` | xs:string? | Yes | The string to test. | +| `suffix` | xs:string? | Yes | The suffix to look for at the end of `string`. | + +## Return value + +`xs:boolean` — `true` if `string` ends with `suffix`, `false` otherwise. + +## Examples + +### Filtering files by extension + +**Input XML:** +```xml + + + report.pdf + data.xml + summary.pdf + stylesheet.xsl + notes.txt + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output:** +```xml + + report.pdf + summary.pdf + +``` + +### Checking namespace URIs + +**Stylesheet:** +```xml + + + + + + + + + + + + + +``` + +## Notes + +- `ends-with()` was introduced in XPath 2.0. In XPath 1.0 there is no built-in equivalent; the workaround is `substring($s, string-length($s) - string-length($suffix) + 1) = $suffix`. +- The comparison is case-sensitive by default. For case-insensitive suffix testing, normalize both strings with `lower-case()` first. +- An empty `suffix` always returns `true`. An empty `string` with a non-empty `suffix` returns `false`. +- `starts-with()` (available in both XPath 1.0 and 2.0) is the complementary function for prefix testing. + +## See also + +- [starts-with()](../xpath-starts-with) +- [contains()](../xpath-contains) +- [substring()](../xpath-substring) +- [lower-case()](../xpath-lower-case) diff --git a/site/content/xslt/functions/xpath-environment-variable.md b/site/content/xslt/functions/xpath-environment-variable.md new file mode 100644 index 00000000..c401b859 --- /dev/null +++ b/site/content/xslt/functions/xpath-environment-variable.md @@ -0,0 +1,99 @@ +--- +title: "environment-variable()" +description: "Returns the value of the named environment variable as a string, or the empty sequence if unavailable." +date: 2026-04-19T00:00:00Z +version: "3.0" +versionLabel: "XSLT 3.0" +category: "node function" +syntax: "environment-variable(name)" +tags: ["xslt", "reference", "xpath", "xslt3"] +--- + +## Description + +`environment-variable()` retrieves the value of a named operating-system or processor-defined environment variable. The function returns the value as a string if the variable is set and accessible, or the empty sequence if it is not available. + +Processors are not required to expose any particular environment variables, and they may choose to expose none at all for security reasons. Use `available-environment-variables()` to discover which variables are accessible before calling this function. The function raises no error when a variable is absent — it simply returns the empty sequence, which can be tested with `exists()` or `empty()`. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `name` | xs:string | Yes | The name of the environment variable to retrieve. | + +## Return value + +`xs:string?` — the value of the environment variable, or the empty sequence if the variable is not set or not accessible. + +## Examples + +### Using an environment variable as a default + +**Input XML:** +```xml + + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output (on a Unix system):** +```xml + + /home/username + username + +``` + +### Checking availability before reading + +**Stylesheet:** +```xml + + + + + + + + Environment: + + + APP_ENV not set — using defaults + + + + +``` + +**Output:** +``` +APP_ENV not set — using defaults +``` + +## Notes + +- Whether environment variables are accessible depends entirely on the processor implementation and security configuration. Saxon exposes OS environment variables by default, but this can be disabled. +- The function is read-only; there is no mechanism in XPath/XSLT to set environment variables. +- Environment variable names are case-sensitive on Unix-like systems and case-insensitive on Windows. +- For production stylesheets, prefer XSLT parameters (`xsl:param`) over environment variables, as parameters are more portable and explicit. + +## See also + +- [available-environment-variables()](../xpath-available-environment-variables) diff --git a/site/content/xslt/functions/xpath-error.md b/site/content/xslt/functions/xpath-error.md new file mode 100644 index 00000000..96d4f7df --- /dev/null +++ b/site/content/xslt/functions/xpath-error.md @@ -0,0 +1,109 @@ +--- +title: "error()" +description: "Raises a dynamic error with an optional error code, description message, and error object." +date: 2026-04-19T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "node function" +syntax: "error(code?, description?, object?)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`error()` raises a dynamic error unconditionally when evaluated. The transformation is aborted unless the error is caught by an `xsl:try/xsl:catch` block (XSLT 3.0). The function is useful for asserting preconditions, documenting unreachable code branches, and raising structured errors with well-defined error codes. + +All three arguments are optional. When called with no arguments, a generic error (`FOER0000`) is raised. When `code` is supplied it must be a `QName` such as `QName('http://example.com/errors', 'e:InvalidInput')`. The `description` is a human-readable string. The `object` is an arbitrary item sequence attached to the error for diagnostic purposes. + +Because `error()` never returns a value, it can be used in any XPath context, including the middle of a conditional expression. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `code` | xs:QName? | No | A QName identifying the error type; defaults to `FOER0000`. | +| `description` | xs:string? | No | A human-readable description of the error. | +| `object` | item()* | No | Arbitrary diagnostic data attached to the error. | + +## Return value + +`error()` never returns; it always raises a dynamic error. + +## Examples + +### Guarding an invalid input + +**Input XML:** +```xml + + + -5 + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + + +``` + +**Output (transformation aborted):** +``` +Dynamic error: Age must be non-negative, got: -5 +``` + +### Catching an error in XSLT 3.0 + +**Stylesheet:** +```xml + + + + + + + + + + + + + + + +``` + +**Output:** +```xml + + Resource missing + +``` + +## Notes + +- `error()` with no arguments raises `FOER0000`; this is the XPath equivalent of an unspecified runtime exception. +- In XSLT 1.0, `xsl:message terminate="yes"` is the closest equivalent since `error()` is not available. +- The `object` argument is accessible as `$err:value` inside an `xsl:catch` block in XSLT 3.0. +- `error()` is typed as returning `none`, which means it is type-compatible with any return type and can appear in the branch of an `if` expression without causing a type error. + +## See also + +- [xsl:message](../xsl-message) +- [trace()](../xpath-trace) +- [exactly-one()](../xpath-exactly-one) diff --git a/site/content/xslt/functions/xpath-exactly-one.md b/site/content/xslt/functions/xpath-exactly-one.md new file mode 100644 index 00000000..bae72d29 --- /dev/null +++ b/site/content/xslt/functions/xpath-exactly-one.md @@ -0,0 +1,109 @@ +--- +title: "exactly-one()" +description: "Asserts that the sequence contains exactly one item; raises a dynamic error if the sequence has zero or more than one item." +date: 2026-04-19T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "sequence function" +syntax: "exactly-one(sequence)" +tags: ["xslt", "reference", "xpath", "xslt2"] +--- + +## Description + +`exactly-one()` is a cardinality assertion function. It returns its argument unchanged if the sequence contains exactly one item, and raises a dynamic error (`FORG0005`) if the sequence is empty or contains more than one item. + +Use `exactly-one()` to make cardinality assumptions explicit in your stylesheets. Rather than silently processing zero or multiple nodes when you expect exactly one, the function causes a clear error with a meaningful location. This is particularly valuable for enforcing schema-like constraints when schema validation is not available. + +The function is purely an assertion; it performs no transformation of the data and has no effect on correct input. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | item()* | Yes | The sequence that must contain exactly one item. | + +## Return value + +`item()` — the single item from the sequence, unchanged. Raises `FORG0005` if the sequence does not contain exactly one item. + +## Examples + +### Asserting a unique key lookup + +**Input XML:** +```xml + + + Alice + Bob + +``` + +**Stylesheet:** +```xml + + + + + + + + + + + +``` + +**Output:** +```xml + + Alice + +``` + +### Catching the error with try/catch (XSLT 3.0) + +**Stylesheet:** +```xml + + + + + + + + + + + No unique employee found: + + + + + +``` + +**Output:** +```xml + + No unique employee found: ... + +``` + +## Notes + +- The error code raised is `err:FORG0005` defined in the XPath/XQuery Functions and Operators specification. +- `exactly-one()` is equivalent to writing `$seq[1][last() = 1]` as a guard, but is cleaner and raises a standard error code. +- In XSLT 2.0 function signatures, the `item()` return type implicitly asserts exactly one item; `exactly-one()` makes that same assertion in an expression context. +- For sequences that may be empty, use `zero-or-one()` instead; for sequences that must be non-empty, use `one-or-more()`. + +## See also + +- [zero-or-one()](../xpath-zero-or-one) +- [one-or-more()](../xpath-one-or-more) +- [error()](../xpath-error) +- [deep-equal()](../xpath-deep-equal) diff --git a/site/content/xslt/functions/xpath-exists.md b/site/content/xslt/functions/xpath-exists.md new file mode 100644 index 00000000..31080301 --- /dev/null +++ b/site/content/xslt/functions/xpath-exists.md @@ -0,0 +1,110 @@ +--- +title: "exists()" +description: "Returns true if the sequence contains at least one item, and false if it is empty." +date: 2026-04-18T00:00:00Z +version: "2.0" +versionLabel: "XSLT 2.0" +category: "sequence function" +syntax: "exists(sequence)" +tags: ["xslt", "reference", "xslt2", "xpath"] +--- + +## Description + +`exists()` tests whether a sequence is non-empty. It returns `true` as soon as it finds at least one item, making it potentially more efficient than `count($seq) gt 0` because it can stop evaluation early. It is the complement of `empty()`. + +While XSLT 1.0 used boolean coercion of node sets (e.g., `if ($nodes)`) to test for existence, `exists()` is the explicit and type-safe XPath 2.0 way to do the same. + +## Parameters + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `sequence` | item()* | Yes | The sequence to test. | + +## Return value + +`xs:boolean` — `true` if the sequence contains one or more items, `false` if it is empty. + +## Examples + +### Conditional output based on element existence + +**Input XML:** +```xml + + +
+ Introduction + Some text here. + + Source: Wikipedia + +
+
+ Main Content + Body text. +
+
+``` + +**Stylesheet:** +```xml + + + + + + + + + + + +
+

+

+ + + +
+
+
+``` + +**Output:** The intro section renders an `