2015-09-30 61 views
1

這是與MarkLogic content pump實用程序相關的第二個問題。Marklogic Content Pump通過XSLT轉換生成多個文檔

我攝入與多個記錄到MarkLogic內容泵單條聚集的XML文檔。我期望將聚合的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文件」上面生成兩個節點:

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變換失敗並返回一個錯誤。那麼,如何修改上述XQuery程序,以便它能夠從單個文檔生成並索引多個轉換後的XML文檔?

鋁塑複合命令:

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 

回答

3

你提供返回包含多個根元件的單個文件變換。該轉換可以工作,但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 

注:轉換函數的map:map*返回類型,這意味着你可以返回零個或多個地圖:地圖的含結果。

HTH!

+0

非常感謝。它是一個救星。請繼續幫助 –

1

不能使用變換函數實際上分裂您的文檔。相反,這稱爲每個文件被攝入

單個文檔的創建是在攝取之前完成的,並由aggregate_標誌控制。

https://docs.marklogic.com/guide/ingestion/content-pump#id_65814

+0

請參考以下鏈接:https://docs.marklogic.com/guide/ingestion/content-pump#id_82518。它清楚地在下面說明(但未提供示例):創建自定義轉換 自定義轉換是符合以下界面的XQuery功能模塊。您的函數接收$ content描述的單個輸入文檔,並且可以生成零個,一個或多個輸出文檔。 –