0
votes

I need to replace the existing node with the new name using MarkLogic of an XML sheet.

I don't use Query Console and I write all my code in .sjs file. When I have gone through the steps given in MarkLogic docs, it is throwing some errors.

Sample code:

<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

I have to change tag "from" and replace it as "sender", ie. expected output:

<note>
  <to>Tove</to>
  <sender>Jani</sender>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

Java Code:

uploading sjs transform from java

DatabaseClient client = DatabaseClientFactory.newClient(IP, 8000,
                           DATABASE_NAME, USERNAME, PWD, Authentication.DIGEST);

// get transform mgr
TransformExtensionsManager transMgr = client.newServerConfigManager()
    .newTransformExtensionsManager();
FileInputStream transStream = null;

try {
    transStream = new FileInputStream(path);
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
InputStreamHandle ipStreamHandle = new InputStreamHandle(transStream);
transMgr.writeJavascriptTransform(JS_TRANSFORM_NAME, ipStreamHandle);
client.release();

Applying the transform before reading the data from MarkLogic. The actual data in database won't be updated

ServerTransform transform = new ServerTransform(transformName);
DatabaseClient client = DatabaseClientFactory.newClient(IP, 8000,
    DATABASE_NAME, USERNAME, PWD, Authentication.DIGEST);
JSONDocumentManager docMgr = clientNew.newJSONDocumentManager();
InputStreamHandle handle = new InputStreamHandle();
docMgr.read("/" + uri + JSON_EXT, handle, transform);
String document = handle.toString();
clientNew.release();
return document;

.sjs code:

declareUpdate();
var n = new NodeBuilder();
node = n.addElement("sender", "Jani").toNode();

xdmp.nodeReplace(
  cts.doc("/example.xml").xpath("/note/from"),
  node
);

Error:

Operation not allowed on the currently executing transaction with identifier declareUpdate
1
Please post what you tried, and how it fails (exact error message, wrong output, ...). - Jens Erat
This is one I tried: xdmp:document-insert("/example.xml", <note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't forget me this weekend!</body></note>); xdmp:nodeReplace(doc("/example.xml")/note/from, <sender>Jack</sender>); - S K padala
ERROR: HTTP Status 500 - Request processing failed; nested exception is com.marklogic.client.FailedRequestException: Local message: config/transforms write failed: Internal Server Error. Server Message: JS-JAVASCRIPT: <note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don't -- Error running JavaScript request: SyntaxError: Unexpected token < . See the MarkLogic server error log for further detail. - S K padala
Better edit those into your original question, code and messages are barely readable in comments. - Jens Erat

1 Answers

4
votes

First, let me note that you can use JavaScript in Query Console (just change the query type). I assume you need to put your code into a file so that it will be part of your application, but running in Query Console is a good way to figure out what code you need.

That said, the code you provided in the comment is a mix of XQuery and JavaScript. xdmp:document-insert() is XQuery -- you can tell by the case, JavaScript doesn't support identifiers with hyphens. The xdmp:nodeReplace should be either xdmp:node-replace (XQuery) or xdmp.nodeReplace (JavaScript).

The problem you've run into is that XML is not valid content in a JavaScript file -- the < and > symbols are interpreted as less than and greater than. You can accomplish what you're trying to do with code like this:

declareUpdate();

var n = new NodeBuilder();
node = n.addElement("sender", "Jani").toNode();

xdmp.nodeReplace(
  cts.doc("/example.xml").xpath("/note/from"),
  node
);

Before going much further, I think you would benefit from reading the Server-side JavaScript introduction. That will give you a better foundation for what you're trying to accomplish.


Edit: In light of additional information from the comments, the solution is that the JavaScript code you're using is intended to update the database, while you want to do a read transformation in memory (Guidelines for Writing Transforms). Based on Writing JavaScript Transformations, here's what you want instead:

function fromToSender(context, params, content) 
{
  var doc = content.toObject();
  delete doc.note.from;
  doc.sender = 'Jani';
  return doc;
};

exports.transform = fromToSender;

Note that this is a library module with a transform called "fromToSender". Adjust as needed.