1

これは、MarkLogic コンテンツ ポンプユーティリティに関連する 2 番目の質問です。

複数のレコードを含む単一の集約された XML ドキュメントを MarkLogic コンテンツ ポンプに取り込んでいます。集約 XML ドキュメントが別の形式に変換され、コンテンツ ポンプ ユーティリティが単一の入力された大きな xml ドキュメントから複数の xml ドキュメントを生成することを期待しています。

例: 集約された入力 xml ドキュメント:

<root>
 <data>Bob</data>
 <data>Vishal></data>
</root>

コンテンツ ポンプからの予期される出力: 異なる形式の 2 つのドキュメント:

文書 1 :

<data1>Bob</data1>

資料2

<data1>Vishal</data1>

上記のドキュメントを 2 つのノードに分割するために、次の 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>

以下は、上記の「XSLT ファイル」を呼び出して 2 つのノードを生成する XQuery 変換です。

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 プログラムを変更して、1 つの文書から複数の変換済み 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 
4

2 に答える 2

3

指定した変換は、複数のルート要素を含む単一のドキュメントを返します。変換は機能しますが、MarkLogic はそれをデータベースに挿入することを許可せず、XDMP-MULTIROOT: Document nodes cannot have multiple roots.

それを解決するには2つの方法があります。最も簡単なのは、/*の後ろで使用することxdmp:xslt-invokeです。もう 1 つの解決策は<xsl:result-document href="{generate-id()}.xml">、XSLT 内で使用することです。どちらも$let-output、単一のドキュメントではなくシーケンスを含むようになります。

ただし、XDMP-CONFLICTINGUPDATES1 つのデータベース 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*。つまり、0 個以上の map:map を含む結果を返すことができます。

チッ!

于 2015-09-30T12:28:13.067 に答える