2015-03-31 66 views
0

我需要使用XML表的MarkLogic替换现有节点。如何替换MarkLogic中的节点?

我不使用查询控制台,而是将所有代码写入.sjs文件。当我经历了MarkLogic文档中给出的步骤时,它会抛出一些错误。

示例代码:

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

我不得不“从”更改标签并替换为“发件人”,即。预期输出:

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

Java代码:

上传SJS从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(); 

变换应用从MarkLogic读取数据之前的变换。在数据库中的实际数据将不会被更新

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代码:

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

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

错误:

Operation not allowed on the currently executing transaction with identifier declareUpdate 
+1

请发布_what_您尝试过,以及它如何失败(确切的错误消息,错误的输出,...)。 – 2015-03-31 12:26:12

+0

这是一个我想: xdmp:文档插入(! “/的example.xml”, 托弗贾尼提醒这个周末不要忘记我); xdmp:nodeReplace(doc(“/ example.xml”)/ note/from, Jack); – 2015-03-31 12:39:12

+0

错误: HTTP状态500 - 请求处理失败;嵌套异常是com.marklogic.client.FailedRequestException:本地消息:config/transforms写入失败:内部服务器错误。服务器消息:JS的JavaScript:托芙贾尼提醒不要 - 错误运行的JavaScript要求:语法错误:意外标记<。有关更多详细信息,请参阅MarkLogic服务器错误日志。 – 2015-03-31 12:41:25

回答

4

首先,我要指出,你可以在查询使用JavaScript控制台(只需更改查询类型)。我假设你需要将你的代码放入一个文件中,这样它才能成为你的应用程序的一部分,但在Query Console中运行是了解你需要什么代码的好方法。

也就是说,您在评论中提供的代码是XQuery和JavaScript的混合。 xdmp:document-insert()是XQuery--您可以通过大小写判断,JavaScript不支持带连字符的标识符。 xdmp:nodeReplace应该是xdmp:node-replace(XQuery)或xdmp.nodeReplace(JavaScript)。

您遇到的问题是,XML在JavaScript文件中无效 - <和>符号被解释为小于和大于。你可以做到你想用代码来执行这样的:

declareUpdate(); 

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

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

之前更大的进展,我想你会从阅读Server-side JavaScript introduction受益。这会为你想要完成的任务提供更好的基础。


编辑: 在从注释附加信息光,该解决方案是,你使用的目的是JavaScript代码来更新数据库,当你想要做一个读取出的转换存储器(Guidelines for Writing Transforms) 。基于Writing JavaScript Transformations,这里有你想要什么,而不是:

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

exports.transform = fromToSender; 

注意,这是一个库模块,该变换称为“fromToSender”。根据需要调整。

+0

谢谢戴夫。 执行上述代码时出现此错误: HTTP状态500 - 请求处理失败;嵌套的异常是com.marklogic.client.FailedRequestException:本地消息:读取失败:内部服务器错误。服务器消息:declareUpdate(); - 当前执行的标识符为declareUpdate的事务不允许操作。有关更多详细信息,请参阅MarkLogic服务器错误日志。 – 2015-04-01 07:25:51

+0

上面的代码将在查询控制台中工作,并应该在主模块(而不是库模块)中工作。我不知道你试图运行它的上下文,所以我不能特别说明你为什么看到这个问题,但一般的答案是,MarkLogic认为你想要做一个查询做一个更新。区别在这里描述:http://docs.marklogic.com/guide/app-dev/transactions#id_40746 – 2015-04-01 11:15:18

+0

我一直在eclipse中处理.java文件,并将以上所有代码写入.sjs并链接到.java文件。然后,我要将它连接到服务器。 这里我还没有使用查询控制台。 – 2015-04-01 12:09:10