0

関数update-replacexdmp:node-replaceで、以下のように呼び出して、MarkLogic の XML データ ソース ファイルの 1 つで XML ノードを動的に置き換えようとしています。

declare function update-lib:update-rec($doc as xs:string, $path as xs:string, $country as xs:string, $name as xs:string, $population as xs:integer, $latitude as xs:decimal, $longitude as xs:decimal) as document-node() {
    (: read lock acquired :)
    fn:doc($doc),

    xdmp:node-replace(fn:doc($doc)/$path,
        <city>
            <country>{$country}</country>
            <name>{$name}</name>
            <population>{$population}</population>
            <latitude>{$latitude}</latitude>
            <longitude>{$longitude}</longitude>
        </city>
    ),


    (: after the following statement, txn ends and locks released :)
    xdmp:commit()
};

この関数は 7 つの引数を取り、最初の引数は XML ソース ファイルへのパス、2 番目の引数は更新するノードへの XML ファイル内のパス、残りは子要素の値に対応します。

データを更新するために呼び出すxdmp:node-replaceと、次のエラーが発生します。

500内部サーバーエラー

XDMP-ARGTYPE: (err:XPTY0004) xdmp:node-replace("/cities/city[3961]", JPMiyoshi56958) -- arg1 は node() 型ではありません ...

そこで、node() が node-replace の最初の引数として渡されるように、arg1 を評価することにしました。

xdmp:node-replace(xdmp:eval(fn:doc($doc)/$path),
    <city>
        <country>{$country}</country>
        <name>{$name}</name>
        <population>{$population}</population>
        <latitude>{$latitude}</latitude>
        <longitude>{$longitude}</longitude>
    </city>
),

代わりに以下のエラーが表示されます。

XDMP-UPEXTNODES: xdmp:node-replace(fn:doc("/content/Users/Tako/Sites/MarkLogic/xml/worldcities/import/cities1000_02.xml")/cities/city[3961], JPMiyoshi56958) -- できません外部ノードを更新します ...

少しグーグルした後、私はこれを見つけました。問題のように聞こえますがxdmp:eval、そのコンテキストは次のとおりです。

http://developer.marklogic.com/pipermail/general/2008-September/001753.html

ここで提案されている回避策を試して、ステートメント全体fn:concatを含めて評価するすべてを文字列として構築しました。xdmp:node-replace

xdmp:eval(fn:concat('xdmp:node-replace(fn:doc("', $doc, '")', $path,
    ', ', '<city><country>',$country,'</country><name>',$name,'</name><population>',$population,'</population><latitude>',$latitude,'</latitude><longitude>',$longitude,'</longitude></city>', ')')),

私がこれを試したとき、アプリケーションはタイムアウトするまで非常に長い時間待機します。500内部サーバーエラー

SVC-EXTIME: xdmp:node-replace(fn:doc("/content/Users/Tako/Sites/MarkLogic/xml/worldcities/import/cities1000_17.xml")/cities/city[3961], JPMiyoshi56958) -- 時間限度超過 ...

私がやりたいことは、更新する XML ファイルとノードを動的に参照し、渡された情報でノードを更新することだけです。非常に基本的なことを見落としているか、これを完全に間違っているに違いありません。

誰かがこれに光を当てることができますか?

4

1 に答える 1

6

最初のソリューションでは、によって返される各ドキュメント ノードに文字列値を適用していますfn:doc($doc)。そうすれば、$xpath自体の文字列値だけが得られます。2 番目のソリューションは、実質的に$xpathの値も取得し、それを評価しようとします。これにより、すべてが更新される可能性がある多くのノードが生成される可能性があります。

XDMP-UPEXTNODESとタイムアウトが発生する理由は完全にはわかりませんが、次のようにする必要があります..

交換:

fn:doc($doc)/$path

と:

xdmp:value(fn:concat("fn:doc($doc)", $path))

チッ!

于 2013-07-02T08:51:38.737 に答える