#Database Extensions
PhoenixmlDb extends XQuery with database-specific functions in the dbxml: namespace. These functions provide access to document metadata and database features directly from XQuery expressions.
#The dbxml: Namespace
The dbxml: namespace (http://phoenixml.endpointsystems.com/dbxml) follows the Berkeley DB XML convention for database extension functions. Declare it in your XQuery prolog:
declare namespace dbxml = "http://phoenixml.endpointsystems.com/dbxml";#dbxml:metadata($node, $key)
Retrieves a specific metadata value for the document containing the given node.
#Signature
dbxml:metadata($node as node(), $key as xs:string) as item()?#Parameters
|
Parameter |
Type |
Description |
|---|---|---|
|
|
|
Any node belonging to the target document |
|
|
|
The metadata key to retrieve |
#Return Type
item()? — The metadata value, or empty sequence if the key does not exist.
#System Metadata Keys
PhoenixmlDb provides built-in system metadata keys prefixed with dbxml::
|
Key |
Type |
Description |
|---|---|---|
|
|
|
Document name within its container |
|
|
|
MIME content type ( |
|
|
|
ISO 8601 creation timestamp |
|
|
|
ISO 8601 last-modified timestamp |
|
|
|
Document size in bytes |
|
|
|
Number of nodes in the document |
#Examples
declare namespace dbxml = "http://phoenixml.endpointsystems.com/dbxml";
(: Get the document name :)
dbxml:metadata(., "dbxml:name")
(: Get a user-defined metadata value :)
dbxml:metadata(., "author")
(: Filter documents by metadata :)
for $doc in collection('products')
where dbxml:metadata($doc, "author") = "admin"
return $doc/product/name/text()
(: Use system metadata in results :)
for $doc in collection('orders')
return <info>
<name>{dbxml:metadata($doc, "dbxml:name")}</name>
<size>{dbxml:metadata($doc, "dbxml:size")}</size>
<author>{dbxml:metadata($doc, "author")}</author>
</info>#dbxml:metadata($node)
Retrieves all user metadata for the document containing the given node as an XQuery map.
#Signature
dbxml:metadata($node as node()) as map(xs:string, item()?)#Parameters
|
Parameter |
Type |
Description |
|---|---|---|
|
|
|
Any node belonging to the target document |
#Return Type
map(xs:string, item()?) — A map of all user-defined metadata key-value pairs.
#Examples
declare namespace dbxml = "http://phoenixml.endpointsystems.com/dbxml";
(: Get all metadata as a map :)
let $meta := dbxml:metadata(.)
return map:keys($meta)
(: Iterate over metadata entries :)
let $meta := dbxml:metadata(.)
for $key in map:keys($meta)
return concat($key, " = ", $meta($key))#Practical Examples
#Filtering by Metadata
declare namespace dbxml = "http://phoenixml.endpointsystems.com/dbxml";
(: Find documents modified after a specific date :)
for $doc in collection('reports')
let $modified := dbxml:metadata($doc, "dbxml:modified")
where $modified > "2024-01-01T00:00:00Z"
return dbxml:metadata($doc, "dbxml:name")#Combining Content and Metadata Queries
declare namespace dbxml = "http://phoenixml.endpointsystems.com/dbxml";
(: Find large orders created by a specific user :)
for $doc in collection('orders')
let $order := $doc/order
where $order/total > 1000
and dbxml:metadata($doc, "author") = "system"
order by xs:decimal($order/total) descending
return <result>
<document>{dbxml:metadata($doc, "dbxml:name")}</document>
<total>{$order/total/text()}</total>
<created>{dbxml:metadata($doc, "dbxml:created")}</created>
</result>#Metadata in FLWOR Expressions
declare namespace dbxml = "http://phoenixml.endpointsystems.com/dbxml";
(: Group documents by author :)
for $doc in collection('articles')
let $author := dbxml:metadata($doc, "author")
group by $author
return <author name="{$author}">
<count>{count($doc)}</count>
<documents>{
for $d in $doc
return <doc>{dbxml:metadata($d, "dbxml:name")}</doc>
}</documents>
</author>#Custom C# Function Extensions
You can register custom XQuery functions from C# by extending the XQueryFunction base class.
#Writing a Custom Function
using PhoenixmlDb.Core;
using PhoenixmlDb.Query.Ast;
public sealed class MyCustomFunction : XQueryFunction
{
public override QName Name => new(
FunctionNamespaces.Local, "my-function");
public override XdmSequenceType ReturnType =>
XdmSequenceType.String;
public override IReadOnlyList<FunctionParameterDef> Parameters =>
[
new() {
Name = new QName(NamespaceId.None, "input"),
Type = XdmSequenceType.String
}
];
public override ValueTask<object?> InvokeAsync(
IReadOnlyList<object?> arguments,
ExecutionContext context)
{
var input = arguments[0]?.ToString() ?? "";
return ValueTask.FromResult<object?>(
input.ToUpperInvariant());
}
}#Registering the Function
var library = FunctionLibrary.Standard;
library.Register(new MyCustomFunction());#Using from XQuery
declare namespace local = "http://www.w3.org/2005/xquery-local-functions";
local:my-function("hello") (: "HELLO" :)#Comparison with Berkeley DB XML
PhoenixmlDb's dbxml:metadata() function is inspired by Berkeley DB XML but with some differences:
|
Feature |
Berkeley DB XML |
PhoenixmlDb |
|---|---|---|
|
Namespace URI |
|
|
|
Metadata access |
|
|
|
All metadata |
Not available |
|
|
System keys |
|
|
|
Custom functions |
Java-based |
C#-based with |