Marklogic Content Pump 通过 XSLT 转换生成多个文档
Marklogic Content Pump generate multiple documents through XSLT transform
这是与MarkLogic content pump实用程序相关的第二个问题。
我正在将包含多个记录的单个聚合 XML 文档提取到 MarkLogic 内容泵中。我希望将聚合 XML 文档转换为不同的格式,并且内容泵实用程序还可以从单个输入大型 xml 文档生成多个 xml 文档。?
示例:聚合输入 xml 文档:
<root>
<data>Bob</data>
<data>Vishal></data>
</root>
内容泵的预期输出:两个格式不同的文档:
文档 1:
<data1>Bob</data1>
文件 2
<data1>Vishal</data1>
我正在使用以下 XSLT 将上述文档拆分为两个节点:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="root">
<xsl:apply-templates select="data"></xsl:apply-templates>
</xsl:template>
<xsl:template match="data">
<data1><xsl:value-of select="."/></data1>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<data1>Bob</data1>
<data1>Vishal</data1>
下面是XQuery转换,调用上面的"XSLT file"生成两个节点:
xquery version "1.0-ml";
module namespace example = "http://marklogic.com/example";
declare function example:transform(
$content as map:map,
$context as map:map
) as map:map*
{
let $attr-value :=
(map:get($context, "transform_param"), "UNDEFINED")[1]
let $the-doc := map:get($content, "value")
let $let-output:= xdmp:xslt-invoke("/marklogic.rest.transform/simple-xsl/assets/transform.xsl", $the-doc )
return (map:put(
$content, "value",
$let-output
),$content)
};
上述 XQuery 转换失败并且 returns 出现错误。那么,我该如何修改上面的 XQuery 程序,以便它从单个文档生成并索引多个转换后的 XML 文档?
MLCP 命令:
mlcp.sh import -host localhost -port 8040 \
-username admin -password admin \
-input_file_path ./parent-form.xml \
-transform_module /example/parent-transform.xqy \
-transform_namespace "http://marklogic.com/example" \
-transform_param "my-value" \
-output_collections people \
-output_permissions my-app-role,read,my-app-role,update
您不能使用转换功能来实际拆分文档。相反,这被称为 每个正在摄取的文档 。
单个文档的创建在摄取之前完成,并由 aggregate_ 标志控制。
https://docs.marklogic.com/guide/ingestion/content-pump#id_65814
您提供的转换 return 是一个包含多个根元素的文档。转换将起作用,但 MarkLogic 不允许将其插入数据库,并抛出 XDMP-MULTIROOT: Document nodes cannot have multiple roots
.
有两种方法可以解决这个问题。最简单的就是在xdmp:xslt-invoke
后面使用/*
。另一种解决方案是在 XSLT 中使用 <xsl:result-document href="{generate-id()}.xml">
。两者都会导致 $let-output
包含一个序列而不是仅包含一个文档。
但是,如果不进行进一步更改,将导致 XDMP-CONFLICTINGUPDATES
,因为这会在一个数据库 uri 中写入多个结果。要解决这个问题,您可以使用一个小技巧克隆 $content map:map
,并提供单独的 uris。比如像这样:
for $let-output at $i in xdmp:xslt-invoke("/marklogic.rest.transform/simple-xsl/assets/transform.xsl", $the-doc )/*
let $extra-content := map:map(document{$content}/*)
let $_ := map:put($extra-content, "value", $let-output)
let $_ := map:put($extra-content, "uri", concat($the-uri, '-', $i, '.xml') )
return
$extra-content
注意:转换函数具有 return 类型 map:map*
,这意味着您可以 return 零个或多个 map:map 包含结果。
HTH!
这是与MarkLogic content pump实用程序相关的第二个问题。
我正在将包含多个记录的单个聚合 XML 文档提取到 MarkLogic 内容泵中。我希望将聚合 XML 文档转换为不同的格式,并且内容泵实用程序还可以从单个输入大型 xml 文档生成多个 xml 文档。?
示例:聚合输入 xml 文档:
<root>
<data>Bob</data>
<data>Vishal></data>
</root>
内容泵的预期输出:两个格式不同的文档:
文档 1:
<data1>Bob</data1>
文件 2
<data1>Vishal</data1>
我正在使用以下 XSLT 将上述文档拆分为两个节点:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="root">
<xsl:apply-templates select="data"></xsl:apply-templates>
</xsl:template>
<xsl:template match="data">
<data1><xsl:value-of select="."/></data1>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<data1>Bob</data1>
<data1>Vishal</data1>
下面是XQuery转换,调用上面的"XSLT file"生成两个节点:
xquery version "1.0-ml";
module namespace example = "http://marklogic.com/example";
declare function example:transform(
$content as map:map,
$context as map:map
) as map:map*
{
let $attr-value :=
(map:get($context, "transform_param"), "UNDEFINED")[1]
let $the-doc := map:get($content, "value")
let $let-output:= xdmp:xslt-invoke("/marklogic.rest.transform/simple-xsl/assets/transform.xsl", $the-doc )
return (map:put(
$content, "value",
$let-output
),$content)
};
上述 XQuery 转换失败并且 returns 出现错误。那么,我该如何修改上面的 XQuery 程序,以便它从单个文档生成并索引多个转换后的 XML 文档?
MLCP 命令:
mlcp.sh import -host localhost -port 8040 \
-username admin -password admin \
-input_file_path ./parent-form.xml \
-transform_module /example/parent-transform.xqy \
-transform_namespace "http://marklogic.com/example" \
-transform_param "my-value" \
-output_collections people \
-output_permissions my-app-role,read,my-app-role,update
您不能使用转换功能来实际拆分文档。相反,这被称为 每个正在摄取的文档 。
单个文档的创建在摄取之前完成,并由 aggregate_ 标志控制。
https://docs.marklogic.com/guide/ingestion/content-pump#id_65814
您提供的转换 return 是一个包含多个根元素的文档。转换将起作用,但 MarkLogic 不允许将其插入数据库,并抛出 XDMP-MULTIROOT: Document nodes cannot have multiple roots
.
有两种方法可以解决这个问题。最简单的就是在xdmp:xslt-invoke
后面使用/*
。另一种解决方案是在 XSLT 中使用 <xsl:result-document href="{generate-id()}.xml">
。两者都会导致 $let-output
包含一个序列而不是仅包含一个文档。
但是,如果不进行进一步更改,将导致 XDMP-CONFLICTINGUPDATES
,因为这会在一个数据库 uri 中写入多个结果。要解决这个问题,您可以使用一个小技巧克隆 $content map:map
,并提供单独的 uris。比如像这样:
for $let-output at $i in xdmp:xslt-invoke("/marklogic.rest.transform/simple-xsl/assets/transform.xsl", $the-doc )/*
let $extra-content := map:map(document{$content}/*)
let $_ := map:put($extra-content, "value", $let-output)
let $_ := map:put($extra-content, "uri", concat($the-uri, '-', $i, '.xml') )
return
$extra-content
注意:转换函数具有 return 类型 map:map*
,这意味着您可以 return 零个或多个 map:map 包含结果。
HTH!