An implementation of XQuery 3.1's fn:unparsed-text* functions for eXist
xquery version "3.1";
(:~
: An implementation of XQuery 3.1's fn:unparsed-text* functions for eXist, which does not support them natively as of 3.4.0.
: Known limitations:
: - Does not enforce encoding aspects of the XQuery spec beyond functionality natively supplied by the EXPath HTTP Client and eXist's internals.
:
: @author Joe Wicentowski
: @version 0.2
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text
:)
module namespace ut="http://joewiz.org/ns/xquery/unparsed-text";
import module namespace hc="http://expath.org/ns/http-client";
(:~
: This function reads an external resource (for example, a file) and returns a string representation of the resource.
: @param $href an absolute URI for a resource for which a string representation is available
: @return a string representation of the resource
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text
:)
declare function ut:unparsed-text($href as xs:string?) as xs:string? {
ut:unparsed-text($href, ())
};
(:~
: This function reads an external resource (for example, a file) and returns a string representation of the resource.
: @param $href an absolute URI for a resource for which a string representation is available
: @param $encoding the name of an encoding
: @return a string representation of the resource
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text
:)
declare function ut:unparsed-text($href as xs:string?, $encoding as xs:string?) as xs:string? {
if ($href castable as xs:anyURI and starts-with($href, "http")) then
let $request :=
<hc:request href="{$href}" method="GET" override-media-type="text/plain">
{
if ($encoding) then
<hc:header name="Accept-Charset" value="{$encoding}"/>
else
()
}
</hc:request>
let $response := hc:send-request($request)
let $response-body := $response[2]
return
$response-body
else if (util:binary-doc-available($href)) then
try {
util:binary-to-string(util:binary-doc($href))
} catch * {
error(xs:QName("err:FOUT1170"), "cannot retrieve the string representation of the resource at " || $href)
}
else
error(xs:QName("err:FOUT1170"), "cannot resolve " || $href || " to an absolute URI")
};
(:~
: This function reads an external resource (for example, a file) and returns its contents as a sequence of strings, one for each line of text in the string representation of the resource.
: @param $href an absolute URI for a resource for which a string representation is available
: @param $encoding the name of an encoding
: @return a sequence of strings, one for each line of text in the string representation of the resource
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text-lines
:)
declare function ut:unparsed-text-lines($href as xs:string?, $encoding as xs:string?) {
let $unparsed-text := ut:unparsed-text($href, $encoding)
return
tokenize($unparsed-text, "\r\n|\r|\n")[not(position() = last() and . = '')]
};
(:~
: This function reads an external resource (for example, a file) and returns its contents as a sequence of strings, one for each line of text in the string representation of the resource.
: @param $href an absolute URI for a resource for which a string representation is available
: @return a sequence of strings, one for each line of text in the string representation of the resource
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text-lines
:)
declare function ut:unparsed-text-lines($href as xs:string?) {
ut:unparsed-text-lines($href, ())
};
(:~
: This function determines whether a call on the fn:unparsed-text function with identical arguments would return a string
: @param $href an absolute URI for a resource for which a string representation is available
: @param $encoding the name of an encoding
: @return true if a call on fn:unparsed-text with the same arguments would succeed, and false if a call on fn:unparsed-text with the same arguments would fail with a non-recoverable dynamic error
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text-available
:)
declare function ut:unparsed-text-available($href as xs:string?, $encoding as xs:string?) as xs:boolean {
if ($href) then
let $attempt := try { ut:unparsed-text($href, $encoding) } catch * { () }
return if (exists($attempt)) then true() else false()
else
()
};
(:~
: This function determines whether a call on the fn:unparsed-text function with identical arguments would return a string
: @param $href an absolute URI for a resource for which a string representation is available
: @return true if a call on fn:unparsed-text with the same arguments would succeed, and false if a call on fn:unparsed-text with the same arguments would fail with a non-recoverable dynamic error
: @see https://www.w3.org/TR/xpath-functions-31/#func-unparsed-text-available
:)
declare function ut:unparsed-text-available($href as xs:string?) as xs:boolean {
ut:unparsed-text-available($href, ())
};