MLCP导入时调用Transform模块遇前缀无命名空间绑定错误
问题:MLCP导入时通过Transform修改文档URI触发前缀无命名空间绑定错误(XDMP-UNBPRFX)
报错信息
23/01/13 15:10:37 INFO contentpump.FileAndDirectoryInputFormat: Total input paths to process : 1 23/01/13 15:10:38 ERROR contentpump.TransformWriter: Batch 361007023.0: Document failed permanently: /opt/mlcp-10.0.9-bin/mlcp-10.0.9/bin/data/EDI_22000041.xml 23/01/13 15:10:38 WARN contentpump.TransformWriter: <error:format-string xmlns:error="http://marklogic.com/xdmp/error" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">XDMP-UNBPRFX: (err:XPST0081) Prefix doc has no namespace binding</error:format-string> 23/01/13 15:10:38 INFO contentpump.LocalJobRunner: completed 100% 23/01/13 15:10:38 INFO contentpump.LocalJobRunner: com.marklogic.mapreduce.MarkLogicCounter: 23/01/13 15:10:38 INFO contentpump.LocalJobRunner: INPUT_RECORDS: 1 23/01/13 15:10:38 INFO contentpump.LocalJobRunner: OUTPUT_RECORDS: 1 23/01/13 15:10:38 INFO contentpump.LocalJobRunner: OUTPUT_RECORDS_COMMITTED: 0 23/01/13 15:10:38 INFO contentpump.LocalJobRunner: OUTPUT_RECORDS_FAILED: 1
Transform模块代码(原错误版本)
xquery version "1.0-ml"; module namespace doc = "http://marklogic.com/example"; declare function doc:uri( $content as map:map, $context as map:map ) as map:map* { let $changeduri := map:get($content, "value")/EDILogFile/DateCreated return ( map:put( $content, "/EDI"||"_"||$changeduri||".xml") ) };
加载Transform模块的XQuery代码(原版本)
xquery version "1.0-ml"; xdmp:document-load("/opt/urichange.xqy", <options xmlns="xdmp:document-load"> <uri>/opt/urichange.xqy</uri> <repair>none</repair> <permissions>{xdmp:default-permissions()}</permissions> </options>)
待导入文件内容
<?xml version="1.0" encoding="UTF-8"?> <EDILogFile xsi:noNamespaceSchemaLocation="file:///Projects/test/schema/LogFile.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ID>****</ID> <SystemRef>22000041</SystemRef> <DateCreated>2022-09-06T19:07:46.3492849+01:00</DateCreated> <TimeSaved>240</TimeSaved> <Production>true</Production> <Partner>test</Partner> <MessageType>test</MessageType> <Fail>false</Fail> <ManyReasons/> <SubmissionUser>test</SubmissionUser> <InternalBusinessUnit>test</InternalBusinessUnit> <Direction>Inbound</Direction> </EDILogFile>
问题排查与解决
1. 命名空间绑定缺失
报错核心是前缀doc无命名空间绑定,原因是MLCP调用Transform模块时,未指定模块对应的命名空间。Transform模块定义了module namespace doc = "http://marklogic.com/example";,因此MLCP命令必须添加-transform_namespace参数指定该命名空间,否则无法识别doc:uri函数。
2. Transform函数参数错误
原代码中map:put用法错误:map:put需要三个参数(map对象、键名、值),修改文档URI应更新$content中的uri键,而非直接传入URI字符串作为第二个参数。
3. 节点值处理不当
$changeduri是XML节点,直接拼接会包含节点标签结构,需提取其字符串值用于URI拼接。
4. 模块加载路径错误
加载Transform模块时,<uri>指定的是本地路径/opt/urichange.xqy,但MLCP调用的是MarkLogic数据库内的模块,因此需将模块加载到数据库内的合理路径(如/urichange.xqy)。
修正后的代码与命令
修正后的Transform模块
xquery version "1.0-ml"; module namespace doc = "http://marklogic.com/example"; declare function doc:uri( $content as map:map, $context as map:map ) as map:map* { let $date-created := string(map:get($content, "value")/EDILogFile/DateCreated) let $new-uri := "/EDI_" || $date-created || ".xml" return map:put($content, "uri", $new-uri) };
修正后的模块加载XQuery
xquery version "1.0-ml"; xdmp:document-load("/opt/urichange.xqy", <options xmlns="xdmp:document-load"> <uri>/urichange.xqy</uri> <!-- 数据库内的模块URI --> <repair>none</repair> <permissions>{xdmp:default-permissions()}</permissions> </options>)
正确的MLCP导入命令示例
mlcp import -host localhost -port 8000 -username admin -password admin \ -input_file_path /opt/mlcp-10.0.9-bin/mlcp-10.0.9/bin/data/EDI_22000041.xml \ -transform_module /urichange.xqy \ -transform_namespace http://marklogic.com/example
内容的提问来源于stack exchange,提问作者Rashmita Purkayastha
相关产品推荐
相关产品推荐

