Как вывести переменные узла из ошибки

#xquery #marklogic

Вопрос:

У меня есть короткая функция, в которой, если что-то пойдет не так на какой-либо части процесса, я могу получить данные из предыдущих частей процесса и записать их для дальнейшего исследования. Например:

 try {
  let $var1 := element outer {
    element inner {"test"}
  }
  let $var2 := element outer2 {
    element inner2 {"test2"}
  }
  let $var3 as xs:string := 2
  return ()
}
catch($e) {
  xdmp:document-insert(
    "testdoc.xml",
    element toplevel {
      element test1 {$e/error:stack/error:frame/error:variables/error:variable[error:name eq "var1"]/error:value},
      element test2 {$e/error:stack/error:frame/error:variables/error:variable[error:name eq "var2"]/error:value}
    }
  )
}
 

Это приводит к записи:

 <toplevel>
  <test1>
    <error:value xmlns:error="http://marklogic.com/xdmp/error"><outer><inner>test</inner></outer></error:value>
  </test1>
  <test2>
    <error:value xmlns:error="http://marklogic.com/xdmp/error"><outer2><inner2>test2</inner2></outer2></error:value>
  </test2>
</toplevel>
 

Когда я хотел бы произвести это:

 <toplevel>
  <test1>
    <outer>
      <inner>test</inner>
    </outer>
  </test1>
  <test2>
    <outer2>
      <inner2>test2</inner2>
    </outer2>
  </test2>
</toplevel>
 

Есть какие-нибудь мысли? Возможно, что в записи «ошибка» хранится только сокращенная версия того, что было в переменной, а не все значение. Если это так, может ли кто-нибудь придумать другой способ получения данных после неожиданного перерыва?

Добавление: Хотя данное решение будет работать для передачи небольших переменных по ошибке, более длинные переменные усекаются.

Комментарии:

1. Это звучит так, как будто $e/error:stack/error:frame/error:variables/error:variable[error:name eq "var1"]/error:value/* вместо $e/error:stack/error:frame/error:variables/error:variable[error:name eq "var1"]/error:value того, чтобы дать вам значения, хотя я предполагаю, что элементы будут иметь пространства имен в области, которые ваш желаемый результат не включает.

2. Нет, это меняет возврат к <toplevel> <test1> </test1> <test2> </test2> </toplevel>

Ответ №1:

Аналогично тому, что предложил Мартин Хоннен в комментариях, но вместо * этого вы можете рассмотреть возможность использования node() , чтобы, если какие-либо переменные не являются элементами, они все равно были выбраны:

 element toplevel {
  element test1 {$e/error:stack/error:frame/error:variables/error:variable[error:name eq "var1"]/error:value/node()},
  element test2 {$e/error:stack/error:frame/error:variables/error:variable[error:name eq "var2"]/error:value/node()}
}
 

Комментарии:

1. Это на правильном пути, но он создает строку узла, а не сам узел. К счастью, мы можем использовать xdmp:unquote, чтобы превратить его обратно в узел.