The REST Client API allows you to create custom content transformations and apply them during operations such as document ingestion and search. Transforms can be implemented as XQuery library modules, XSLT stylesheets, or server-side JavaScript modules, and can accept transform-specific parameters. Transforms can be applied on any REST Client API service that accepts a transform
parameter.
This chapter covers the following topics:
This section covers the following topics related to authoring transform functions:
Keep the following guidelines in mind when authoring a transform:
To create a JavaScript transformation, implement a server-side JavaScript module that implements function with the following interface and exports it with the name transform
:
function yourTransformName(context, params, content) { ... }; exports.transform = yourTransformName;
Your implementation must use the MarkLogic server-side JavaScript dialect. For details, see the JavaScript Reference Guide.
Resource service extensions, transforms, row mappers and reducers, and other hooks on the REST API cannot be implemented as JavaScript MJS modules.
The table below describes the parameters:
Parameter | Description |
---|---|
context |
An object containing service request context information such as input document types and URIs, and output types accepted by the caller. For details, see Context Map Keys. |
params |
An object containing the extension-specific parameters, if any. The object contains an object property for each request parameter with a trans: prefix. If you specify the same parameter name more than once, the property value is an array. You can optionally define parameter name and type metadata when installing the extension. For details, see Installing Transformations. |
content |
The input document to which to apply the transformation. For example, the document being inserted into the database if the transform is applied during ingestion, or a search:response if the transform is applied during a search. For details, see Expected Input and Output. |
Note that content
is document node, not a JavaScript object. If content
is a JSON document, you must call toObject
on it before you can manipulate the content as a JavaScript object or modify it. For example:
const mutableDoc = content.toObject();
The expected output from your transform function depends upon the situation in which it is used. For details, see Expected Input and Output.
For a complete example, see JavaScript Example: Adding a JSON Property During Ingestion.
To create an XQuery transformation, implement an XQuery library module in the following namespace:
http://marklogic.com/rest-api/transform/yourTransformName
Where yourTransformName is the name used to refer to the transform in subsequent REST requests, such as installing and applying the transform.
The module must implement a public function called transform
with the following interface:
declare function yourNS:transform( $context as map:map, $params as map:map, $content as document-node()) as document-node()
The table below describes the parameters:
Parameter | Description |
---|---|
$context |
Service request context information such as input document type and URI, and output types accepted by the caller. For details, see Context Map Keys. |
$params |
Transformation specific parameters. The map contains a key for each transform parameter passed to the request for which the transform is applied. Define parameters when installing the transformation. For details, see Installing Transformations. |
$content |
The input document to which to apply the transformation. For example, the document being inserted into the database if the transform is applied during ingestion, or a search:response if the transform is applied during a search. For details, see Expected Input and Output. |
The map:map type is a MarkLogic Server extended XQuery type representing a key-value map. For details, see Using the map Functions to Create Name-Value Maps in the Application Developer's Guide.
The expected output from your transform function depends upon the situation in which it is used. For details, see Expected Input and Output.
For a complete example, see XQuery Example: Adding an Attribute During Ingestion.
To create an XSLT transformation, implement an XSLT stylesheet that accepts the following parameters:
Parameter | Type | Description |
---|---|---|
$context |
map:map |
Service request context information such as input document type and URI, and output types accepted by the caller. For details, see Context Map Keys. |
$params |
map:map |
Transformation specific parameters. The map contains a key for each transform parameter passed to the request for which the transform is applied. Define any parameters when installing the transformation. For details, see Installing Transformations. |
The map:map type is a MarkLogic Server extended XQuery type representing a key-value map. For details, see Using the map Functions to Create Name-Value Maps in the Application Developer's Guide.
To use the map
type in your stylesheet, include the namespace http://marklogic.com/xdmp/map
. Reference the map contents using the map:get XQuery function.
The following example illustrates declaring the map
namespace and $context
and $params
parameters, and referencing values in the $params
map:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:example="http://marklogic.com/rest-api/example/transform" xmlns:map="http://marklogic.com/xdmp/map"> <xsl:param name="context" as="map:map"/> <xsl:param name="params" as="map:map"/> <xsl:template match="/*"> <xsl:copy> <xsl:attribute name='{(map:get($params,"name"),"transformed")[1]}' select='(map:get($params,"value"),"UNDEFINED")[1]'/> ...
The expected output from your transform function depends upon the situation in which it is used. For details, see Expected Input and Output.
For a complete example, see XSLT Example: Adding an Attribute During Ingestion.
The input document ($content
) to a transform is always a document. The format and contents of the document depend on where the transform is used. The following table summarizes the expected input and output for a transform function for the supported use cases.
A transform applied to a search operation should expect to receive either a search results summary, such as a <search:response/>
, or a document matched by the query. A search request can return a search result summary, a set of matching documents, or both, depending on the request parameters, Accept headers, and query options. For details, see What to Expect as Input Content.
This section discusses proper error reporting in your transform or service resource extension implementation. Use the approach described here for both XQuery and XSLT implementations. For more information about error reporting conventions, see Error Reporting.
To report an error from your implementation, use the fn:error
XQuery function with the RESTAPI-SRVEXERR
error code, and provide the HTTP response code and additional error information in the 3rd parameter to fn:error.
The 3rd parameter to fn:error should be a sequence of the form ("
status-code", "
status-message", "
response-payload")
. That is, when using fn:error to raise RESTAPI-SRVEXERR
, the $data
parameter to fn:error is a sequence with the following members, all optional:
Best practice is to use RESTAPI-SRVEXERR
. If you report any other error or raise any other exception, it is reported to the calling application as a 500 Server Internal Error.
For example, this resource extension function raises RESTAPI-SRVEXERR
if the input content type is not as expected:
declare function example:transform( $context as map:map, $params as map:map, $input as document-node() ) as document-node() { (: get 'input-types' to use in content negotiation :) let $input-types := map:get($context,"input-types") let $negotiate := if ($input-types = "application/xml") then () (: process, insert/update :) else fn:error((),"RESTAPI-SRVEXERR", ("415","tsk tsk","whoops")) return document { "Done"} (: may return a document node :) };
If a PUT request is made to the transform with an unexpected content type, the fn:error call causes the request to fail with a status 415 and to include the additional error description in the response body:
HTTP/1.1 415 tsk tsk Content-type: application/xml Server: MarkLogic Set-Cookie: SessionID=714070bdf4076536; path=/ Content-Length: 62 Connection: close { "message": "js-example: response with invalid 400 status", "statusCode": 415, "body": { "errorResponse": { "statusCode": 415, "status": "tsk tsk", "messageCode": "RESTAPI-SRVEXERR", "message": "whoops" } } }
The context map parameter made available to transformations can contain the following keys:
This section discusses the default transaction mode under which your content transformation is evaluated, and how you can override the default behavior when using an XQuery transform. You cannot control transaction context for a JavaScript transform.
This discussion assumes you are familiar with the MarkLogic Server transaction mode concept; for details, see Transaction Mode in Application Developer's Guide.
The default transaction mode for a transformation function depends on the request on whose behalf it is applied:
/documents
: update/documents
: query/search
, /qbe
, /values
): queryChoosing the appropriate transaction mode can improve the resource utilization of your implementation. For example, an update transaction acquires exclusive locks on documents, as described in Update Transactions: Readers/Writers Locks in Application Developer's Guide. If you know that your transformation is actually a read-only operation, you can override the default transaction mode so that the function is evaluated in query transaction mode and does not acquire exclusive locks.
To override the default behavior, include a transaction mode annotation in the declaration of your function:
declare %rapi:transaction-mode("the-mode") function yourNS:transform
(...)
The value for %rapi:transaction-mode
can be either update or query.
For example, to specify query transaction mode for your transform
function, use the following declaration:
declare %rapi:transaction-mode("query") function example:transform( $context as map:map, $params as map:map, $content as document-node()) as document-node() {...};
This section covers the following topics:
To install or update a transformation, use PUT /v1/config/transforms/{name}. Send a PUT request with a URL of the following form, with the transform code in the request body:
http://host:port/version/config/transforms/yourTransformName
Where yourTransformName is the name used when administering and applying the transformation. You can optionally include informational metadata about your transform during installation; for details, see Including Transform Metadata.
If you are installing an XQuery transform, yourTransformName must match the leaf name in the transform module namespace declaration. For example:
xquery version "1.0-ml"; module namespace example = "http://marklogic.com/rest-api/transform/yourTransformName"; ...
Set the Content-type
of the request to one of the following, depending on the language in which you implement your transformation:
application/xquery
application/vnd.marklogic-javascript
application/xslt+xml
For example, the following command installs a JavaScript transform under the name js-example:
# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X PUT -i \ --data-binary @"./trans-ex.sjs" \ -H "Content-type: application/vnd.marklogic-javascript" \ 'http://localhost:8000/LATEST/config/transforms/js-example'
If your transform requires additional assets such as user-defined XQuery or JavaScript library modules, you must install them separately before installing your transform. For details, see Using a Resource Service Extension.
You can optionally include metadata for provider
, version
, title
, description
and caller-supplied parameters as request parameters during installation. Metadata can be retrieved using GET /v1/config/transforms. See Discovering Transformations.
For example, the following transform installation includes metadata about the provider:
http://host:port/version/config/transforms/example?provider=MarkLogic%20Corporation
The optional parameter metadata identifies the name, type, and cardinality of parameters the client can supply when apply the transform to a read, write or search. Include the parameter metadata as request parameters of the following form:
trans:paramName=paramTypeAndCardinality
Where paramName is the name of the parameter and paramTypeAndCardinality reflects the type and cardinality the parameter would have in an XQuery function declaration.
For example, string? means a string type parameter which may appear 0 or 1 time. The following URL illustrates a transform called example with an optional string parameter named reviewer:
http://host:port/version/config/transforms/example?trans:reviewer=string\?
All REST Client API services that support transformations use the following mechanism for specifying application of a transformation:
transform
request parameter: transform=transformName
trans:paramName=value
For example, to apply a transform during document insertion, you can send a PUT request to the /documents
service with a transform
request parameter. Assuming the transform called example expects one parameter named reviewer, the PUT request URL might look like the following:
http://host:port/version/documents?uri=/doc/theDoc.xml&transform=example&trans:reviewer=me
You could apply the same transformation during document retrieval by sending a GET request to the /documents
service with the same URL.
Use GET /v1/config/transforms to discover the name, interface, and other metadata about installed transformations. Send a GET request to the /config/transforms
service of the form:
http://host:port/version/config/transforms
MarkLogic Server returns a summary of the installed transforms in XML or JSON. The default summary format is XML. Use the Accept header or format
request parameter to select the output content type. For details, see Controlling Input and Output Content Type.
By default, this request rebuilds the transform metadata each time it is called to ensure the metadata is up to date. If you find this refresh makes discovery take too long, you can disable the refresh by setting the refresh
request parameter to false. Disabling the refresh can result in this request returning inaccurate information, but it does not affect the freshness or availability of the implementation of any transforms.
The following example requests an XML report:
# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X GET \ -H "Accept: application/xml" \ http://localhost:8000/LATEST/config/transforms ... HTTP/1.1 200 Transform List Retrieved Content-type: application/xml Server: MarkLogic Content-Length: 348 Connection: close <?xml version="1.0" encoding="UTF-8"?> <rapi:transforms xmlns:rapi="http://marklogic.com/rest-api"> <rapi:transform> <rapi:name>add-attr-xsl</rapi:name> <rapi:title/> <rapi:version/> <rapi:provider-name>MarkLogic Corporation</rapi:provider-name> <rapi:description/> <rapi:transform-parameters> <rapi:parameter> <rapi:parameter-name>value</rapi:parameter-name> <rapi:parameter-type>string?</rapi:parameter-type> </rapi:parameter> <rapi:parameter> <rapi:parameter-name>name</rapi:parameter-name> <rapi:parameter-type>string?</rapi:parameter-type> </rapi:parameter> </rapi:transform-parameters> <rapi:transform-source> /v1/transforms/add-attr </rapi:transform-source> </rapi:transform> </rapi:transforms>
To retrieve the XQuery code or XSLT stylesheet that implements a transformation, send a GET request to the /config/transforms/{name}
service of the form:
http://host:port/version/config/transforms/transformName
Where transformName is the name under which the extension is installed.
Set the request Accept header to one of the following MIME types. The type must match the implementation language of the transform.
application/xquery
application/vnd.marklogic-javascript
application/xslt+xml
MarkLogic Server returns the XQuery library module or XSLT stylesheet that implements the transform in the response body. For example:
# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X GET \ -H "Accept: application/xquery" \ http://localhost:8000/LATEST/config/transforms/example ... xquery version "1.0-ml"; module namespace example="http://marklogic.com/rest-api/transform/example"; declare function example:transform( ...
This example demonstrates a transformation that adds a property to a JSON document. The first example in this section adds a property with a fixed name and a value corresponding to the current dateTime. The second example adds a property corresponding to a name and value passed in as transform parameters.
When used as a read transform, the following transform adds a property named readTimestamp
to the content returned to the client. When used as a write transform, it adds a property named writeTimestamp
to the document stored in the database. In both cases, the value of the property is the dateTime at the time of the operation. If the input document is not JSON, the content is unchanged on both read and write.
Follow these steps to exercise the transform:
function insertTimestamp(context, params, content) { if (context.inputType.search('json') >= 0) { const result = content.toObject(); if (context.acceptTypes) { /* read */ result.readTimestamp = fn.currentDateTime(); } else { /* write */ result.writeTimestamp = fn.currentDateTime(); } return result; } else { /* Pass thru for non-JSON documents */ return content; } }; exports.transform = insertTimestamp;
# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X PUT -i \ --data-binary @"./trans-ex.sjs" \ -H "Content-type: application/vnd.marklogic-javascript" \ 'http://localhost:8000/LATEST/config/transforms/js-example'
$ curl --anyauth --user user:password -X GET \ -H "Accept: application/json" \ http://localhost:8000/LATEST/config/transforms { "transforms": { "transform": [ { "name": "js-example", "source-format": "javascript", "transform-parameters": "", "transform-source": "/v1/config/transforms/example" } ] }
$ curl --anyauth --user user:password -X PUT -d'{"name":"value"}' \ -H "Content-type: application/json" \ 'http://localhost:8000/LATEST/documents?uri=/transforms/example.json&transform=js-example'
writeTimestamp
attribute. For example:$ curl --anyauth --user user:password -X GET \ -H "Accept: application/json" \ http://localhost:8000/LATEST/documents?uri=/transforms/example.json { "key":"value", "writeTimestamp":"2014-11-25T16:59:00.459241-08:00" }
$ curl --anyauth --user user:password -X GET \ -H "Accept: application/json" \ 'http://localhost:8000/LATEST/documents?uri=/transforms/example.json&transform=js-example' { "key":"value", "writeTimestamp":"2014-11-25T16:59:00.459241-08:00", "readTimestamp":"2014-11-25T17:38:28.417881-08:00" }
The writeTimestamp
is unchanged since it is part of the document. The readTimestamp
is an artifact of the read, rather than part of the document. It will change each time you apply the transform during the read.
The following function is an alternative transform that demonstrates passing in transform parameters. For each parameter passed in via trans:
name=
value, the transform inserts a JSON property with the same name and value. The transform is applicable to both read and write operations. As before, non-JSON documents are unchanged.
function insertProperty(context, params, content) { if (context.inputType.search('json') >= 0 && params) { const result = content.toObject(); Object.keys(params).forEach(function(key) { result[key] = params[key]; }); return result; } else { // Pass thru unchanged return content; } }; exports.transform = insertProperty;
The following example commands demonstrate using this transform on a read operation, assuming the transform is installed with the name ex-params:
$ curl --anyauth --user user:password -X GET \ -H "Accept: application/json" -i \ 'http://localhost:8000/LATEST/documents?uri=/transforms/example.json&transform=ex-params&trans:prop1=42&trans:prop2=dog' ... { "key":"value", "writeTimestamp":"2014-11-25T16:59:00.459241-08:00", "prop1":"42", "prop2":"dog" }
You can specify the same parameter more than once. For example, if the request parameter prop1 is supplied more than once, the value of prop1 is an array.
http://localhost:8000/LATEST/documents?...&trans:prop1=42&trans:prop1=43 ==> { ..., "prop1":["42", "43"] }
This example demonstrates using a transformation to add an attribute to the root node of an XML document during ingestion. The name and value of the added attribute are passed in as parameters to the transform function. You can use the same transform for document retrieval by applying it to a GET request instead of a PUT.
The transformation XQuery module shown below reads the attribute name and value from parameters, and then makes a copy of the input document, adding the requested attribute to the root node. The transformation cannot perform direct transformations on the input XML, such as calling xdmp:node-replace, because the document has not yet been inserted into the database when the transform function runs.
xquery version "1.0-ml"; module namespace example = "http://marklogic.com/rest-api/transform/add-attr"; declare function example:transform( $context as map:map, $params as map:map, $content as document-node() ) as document-node() { if (fn:empty($content/*)) then $content else let $value := (map:get($params,"value"),"UNDEFINED")[1] let $name := (map:get($params, "name"), "transformed")[1] let $root := $content/* return document { $root/preceding-sibling::node(), element {fn:name($root)} { attribute { fn:QName("", $name) } {$value}, $root/@*, $root/node() }, $root/following-sibling::node() } };
/config/transforms/{name}
service to install the transform as add-attr, accepting 2 string parameters called name and value. For example:# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X PUT -d@"./add-attr.xqy" \ -H "Content-type: application/xquery" \ 'http://localhost:8000/LATEST/config/transforms/add-attr?trans:name=string\?&trans:value=string\?'
/config/transforms
service. For example:$ curl --anyauth --user user:password -X GET -i \ -H "Accept: application/xml" \ http://localhost:8000/LATEST/config/transforms ... HTTP/1.1 200 Transform List Retrieved Content-type: application/xml Server: MarkLogic Content-Length: 348 Connection: close <?xml version="1.0" encoding="UTF-8"?> <rapi:transforms xmlns:rapi="http://marklogic.com/rest-api"> <rapi:transform> <rapi:name>add-attr</rapi:name> <rapi:source-format>xquery</rapi:source-format> <rapi:title/> <rapi:version/> <rapi:provider-name/> <rapi:description/> <rapi:transform-parameters> <rapi:parameter> <rapi:parameter-name>value</rapi:parameter-name> <rapi:parameter-type>string?</rapi:parameter-type> </rapi:parameter> <rapi:parameter> <rapi:parameter-name>name</rapi:parameter-name> <rapi:parameter-type>string?</rapi:parameter-type> </rapi:parameter> </rapi:transform-parameters> <rapi:transform-source> /v1/transforms/add-attr </rapi:transform-source> </rapi:transform> </rapi:transforms>
/documents
service to insert a document into the database, using the add-attr transform to add the attribute example with a value of new. For example:$ curl --anyauth --user user:password -X PUT -d"<data/>" \ 'http://localhost:8000/LATEST/documents?uri=/doc/transformed.xml&transform=add-attr&trans:name=example&trans:value=new'
/documents
service to retrieve the inserted document. Note the added example attribute. For example:$ curl --anyauth --user user:password -X GET \ http://localhost:8000/LATEST/documents?uri=/doc/transformed.xml <?xml version="1.0" encoding="UTF-8"?> <data example="new"/>
This example demonstrates using a transformation to add an attribute to the root node of an XML document during ingestion. The name and value of the added attribute are passed in as parameters to the stylesheet. You can use the same transform for document retrieval by applying it to a GET request instead of a PUT.
The transformation stylesheet shown below reads the attribute name and value from parameters, and then makes a copy of the input document, adding the requested attribute to the root node.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:example="http://marklogic.com/rest-api/example/transform" xmlns:map="http://marklogic.com/xdmp/map"> <xsl:param name="context" as="map:map"/> <xsl:param name="params" as="map:map"/> <xsl:template match="/*"> <xsl:copy> <xsl:attribute name='{(map:get($params,"name"),"transformed")[1]}' select='(map:get($params,"value"),"UNDEFINED")[1]'/> <xsl:copy-of select="@*"/> <xsl:copy-of select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
/config/transforms/{name}
service to install the transform as add-attr-xsl, accepting 2 string parameters called name and value. For example:# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X PUT -d@"./add-attr.xsl" \ -H "Content-type: application/xslt+xml" \ 'http://localhost:8000/LATEST/config/transforms/add-attr-xsl?trans:name=string\?&trans:value=string\?'
$ curl --anyauth --user user:password -X GET \ -H "Accept: application/xml" \ http://localhost:8000/LATEST/config/transforms ... HTTP/1.1 200 Transform List Retrieved Content-type: application/xml Server: MarkLogic Content-Length: 348 Connection: close <?xml version="1.0" encoding="UTF-8"?> <rapi:transforms xmlns:rapi="http://marklogic.com/rest-api"> <rapi:transform> <rapi:name>add-attr-xsl</rapi:name> <rapi:source-format>xslt</rapi:source-format> <rapi:title/> <rapi:version/> <rapi:provider-name/> <rapi:description/> <rapi:transform-parameters> <rapi:parameter> <rapi:parameter-name>value</rapi:parameter-name> <rapi:parameter-type>string?</rapi:parameter-type> </rapi:parameter> <rapi:parameter> <rapi:parameter-name>name</rapi:parameter-name> <rapi:parameter-type>string?</rapi:parameter-type> </rapi:parameter> </rapi:transform-parameters> <rapi:transform-source> /v1/transforms/add-attr </rapi:transform-source> </rapi:transform> </rapi:transforms>
PUT:/v1/documents
request to insert a document into the database, using the add-attr-xsl transform to add the attribute example with a value of new. For example:$ curl --anyauth --user user:password -X PUT -d"<data/>" \ 'http://localhost:8000/LATEST/documents?uri=/doc/transformed.xml&transform=add-attr-xsl&trans:name=example&trans:value=new'
$ curl --anyauth --user user:password -X GET \ http://localhost:8000/LATEST/documents?uri=/doc/transformed.xml <?xml version="1.0" encoding="UTF-8"?> <data example="new"/>
This example is a write transform that converts JSON input into XML, inserting an XML document into the database. It also demonstrates modifying the context map to change the document URI.
When you insert a document with a PUT or POST request to the /documents
service and specify a transform function name, the MIME type in the Content-type request header takes precedence over the URI extension in determining the format of the data in the request body.
The following transform takes advantage of this behavior to accept JSON input and convert it to XML. The transform also modifies the URI to match, if necessary: If the URI has a .json URI suffix, the URI is modified to have a .xml suffix by modifying the value of the uri key in the $context
map.
xquery version "1.0-ml"; module namespace xqjson2xml = "http://marklogic.com/rest-api/transform/xqjson2xml"; import module namespace json="http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy"; declare function xqjson2xml:transform( $context as map:map, $params as map:map, $content as document-node() ) as document-node() { if (fn:contains(map:get($context, "input-type"), "json")) then ( map:put($context, "output-type", "application/xml"), let $uri := map:get($context, "uri") return if (fn:ends-with($uri, ".json")) then map:put($context, "uri", fn:concat(fn:substring-before($uri, ".json"), ".xml")) else (), document {json:transform-from-json($content)} ) else $content };
/config/transforms/{name}
service to install the transform as xqjson2xm. For example:# Windows users, see Modifying the Example Commands for Windows $ curl --anyauth --user user:password -X PUT -d@"./json2xml.xqy" \ -H "Content-type: application/xquery" \ 'http://localhost:8000/LATEST/config/transforms/xqjson2xml'
/config/transforms
service. For example:$ curl --anyauth --user user:password -X GET -i \ -H "Accept: application/xml" \ http://localhost:8000/LATEST/config/transforms
/documents
service to insert a document into the database with a .xml extension, using the xqjson2xml transform. Note the request payload is JSON, but an XML document is inserted into the database.$ curl --anyauth --user user:password -i -X PUT \ -d'{"a": "b"}' -H "Content-type: application/json" \ 'http://localhost:8000/LATEST/documents?uri=/doc/j2x.xml&transform=xqjson2xml'
/documents
service to retrieve the inserted XML document. For example:$ curl --anyauth --user user:password -X GET \ 'http://localhost:8000/LATEST/documents?uri=/doc/j2x.xml' ... HTTP/1.1 200 OK vnd.marklogic.document-format: xml Content-type: application/xml; charset=utf-8 Server: MarkLogic Content-Length: 134 Connection: Keep-Alive Keep-Alive: timeout=5 <?xml version="1.0" encoding="UTF-8"?> <json type="object" xmlns="http://marklogic.com/xdmp/json/basic"><a type="string">b</a></json>
/documents
service to insert a document into the database, using the xqjson2xml transform, but this time with a URI with a .json suffix. The transform modifies both the document type and the URI extension.$ curl --anyauth --user user:password -i -X PUT \ -d'{"c": "d"}' -H "Content-type: application/json" \ 'http://localhost:8000/LATEST/documents?uri=/doc/j2x_2.json&transform=xqjson2xml'
/documents
service to retrieve the inserted XML document, using the modified URI. For example:$ curl --anyauth --user user:password -X GET \ 'http://localhost:8000/LATEST/documents?uri=/doc/j2x_2.xml' ... HTTP/1.1 200 OK vnd.marklogic.document-format: xml Content-type: application/xml; charset=utf-8 Server: MarkLogic Content-Length: 134 Connection: Keep-Alive Keep-Alive: timeout=5 <?xml version="1.0" encoding="UTF-8"?> <json type="object" xmlns="http://marklogic.com/xdmp/json/basic"><c type="string">d</c></json>
Note that you can write a similar transformation in JavaScript.