Как вернуть полный документ, используя xdmp: node-replace ()? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть требование, когда мне нужно вернуть полный документ после завершения всего процесса.

Мое последнее утверждение имеет xdmp:node-replace() и, следовательно, возвращает empty sequence.

Узлы заменяются в моем окончательном документе, но я не могу увидеть их на консоли в 1-м запуске.Когда я запускаю его во второй раз, тогда я могу видеть замененный узел.

Вот пример кода -

abc.xml--->
  <root>
       <id>abcd</id>
  </root>

let $doc := doc("abc.xml")
 (: Let $doc is having an Id node :)

let $replace := xdmp:node-replace($doc//id,<id>1234</id>)
  return $doc

Actual Output-->
 <root>
       <id>abcd</id>
  </root>

 Expected Output-->
   <root>
       <id>1234</id>
  </root>

Если я вернусь $replace, то это даст мнеempty sequence

Я хочу вернуть ожидаемый результат в 1-й серии

Есть предложения?

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018

Вы можете использовать транзакцию с несколькими операторами, , используя точку с запятой , чтобы отделить транзакцию записи от транзакции чтения, чтобы вы могли видеть обновление.

xquery version "1.0-ml";
xdmp:node-replace(doc("abc.xml")//id, <id>1234</id>)
;

xquery version "1.0-ml";
doc("abc.xml")
0 голосов
/ 30 ноября 2018

Другая альтернатива для изменения в памяти будет через XSLT.Используя преобразование идентичности, создайте шаблоны, соответствующие узлам, которые вы хотите изменить:

xquery version "1.0-ml";
declare variable $XSLT := 
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="id/text()">
        <xsl:text>1234</xsl:text>
    </xsl:template>

  </xsl:stylesheet>;

let $doc := doc("abc.xml")
let $modified := xdmp:xslt-eval($XSLT, $doc)
return 
  ( xdmp:node-replace($doc, $modified), $modified )
0 голосов
/ 29 ноября 2018

xdmp:node-replace заменяет узлы в базе данных, а не в памяти.Также вы не можете видеть обновления базы данных перед фиксацией.

Простым решением было бы создать обновленный документ в памяти и вернуть его.

xquery version "1.0-ml";

xdmp:document-insert("abc.xml",
<root>
  <id>abcd</id>
  <name>Test</name>
</root>
);

let $doc := doc("abc.xml")
let $update := 
<root>
    <id>1234</id>
    {$doc/root/name}
</root>

return (
  xdmp:document-insert("abc.xml", $update), 
  $update
)

Редактировать:

Альтернатива с использованием функции замены в памяти:

xquery version "1.0-ml";

import module namespace mem = "http://xqdev.com/in-mem-update" at '/MarkLogic/appservices/utils/in-mem-update.xqy';

let $doc := doc("abc.xml")
let $updatedDoc := mem:node-replace($doc//id, <id>1234</id>)

return (
  xdmp:node-replace($doc, $updatedDoc),
  $updatedDoc
)

С точки зрения производительности, я думаю, что мои и альтернативы Мадс Хансен имеют одинаковые характеристики производительности,Я бы сказал, выбрать то, что вам нравится больше всего.Я использовал свой подход для простых случаев использования обновлений много, для более сложных случаев использования, которые могут также включать перемещение узлов или около того, я бы предпочел использовать альтернативу Мадс Хансен XSLT.

...