MarkLogic json: transform-from-json с несколькими пространствами имен? - PullRequest
1 голос
/ 16 апреля 2019

В MarkLogic можно ли использовать json: transform-from-json для преобразования json в XML с несколькими пространствами имен? Например, как конвертировать

{
  options: {
    format: "xml"
  }
}

в

<options xmlns="xdmp:http-get">
  <format xmlns="xdmp:document-get">xml</format>
</options>

Ответы [ 2 ]

1 голос
/ 20 апреля 2019

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

Если вы используете json:transform-from-json(), результирующий XML будет находиться в пространстве имен http://marklogic.com/xdmp/json/basic.

<json type="object" xmlns="http://marklogic.com/xdmp/json/basic">
  <options type="object">
    <format type="string">xml</format>
  </options>
</json>

Затем вам нужно будет преобразовать этот XML, чтобы получить эти элементы в нужных пространствах имен. Один из способов сделать это - использовать рекурсивную функцию переключения типов:

xquery version "1.0-ml";
declare namespace j = "http://marklogic.com/xdmp/json/basic";
import module namespace json="http://marklogic.com/xdmp/json"
 at "/MarkLogic/json/json.xqy";

declare function local:convert($node as node()) as item()* {
  typeswitch($node)
    case attribute() return ()
    case element(j:json) return local:convert($node/node())
    case element(j:options) return element {fn:QName("xdmp:http-get", $node/local-name())} {local:convert($node/node())}
    case element() return element {fn:QName("xdmp:document-get", $node/local-name())} {local:convert($node/node())}
    default return $node
};

let $json := '{
  options: {
    format: "xml"
  }
}'

return local:convert(json:transform-from-json( $json ))

Однако, если вы пытаетесь создать XML для построения опций для xdmp:document-get(), вы можете указать, что проще указать опции, используя map:map вместо формы XML.

Параметры, с помощью которых можно настроить эту операцию. Вы можете указать параметры как элемент XML в пространстве имен «xdmp: document-get» или как map:map. Имена параметров ниже являются локальными именами элементов XML. При использовании карты замените дефисы верблюжьей оболочкой. Например, «an-option» становится «anOption» при использовании в качестве ключа map: map.

Если у вас есть объект JSON, вы можете выбрать свойство options и затем использовать fn:data() или xdmp:from-json(), чтобы атомизировать объектный узел options как карту:

fn:data($json//options)
1 голос
/ 18 апреля 2019

Да, вы можете, это не документировано или просто, но это не секрет. Посмотрите на источник в Modules / MarkLogic / json / custom.xqy

Существует намного больше пользовательских параметров, чем задокументировано. «Интересные» позволяют переопределить отдельные методы, используемые для преобразования. Пример: при использовании пользовательской стратегии вы можете установить переопределения. Ниже приведены значения по умолчанию, вы можете изменить их.

map:put($c , $json-custom:element-qname-from-json-name  , json-custom:element-qname-from-json-name#2 ),
map:put($c , $json-custom:attribute-qname-from-json-name  , json-custom:attribute-qname-from-json-name#2 ),

Замените функцию 'json-custom: element-qname-from-json-name' своей собственной - вы можете использовать любую логику, какую пожелаете, учитывая объект конфигурации и текущее имя поля json, возвращая полное имя QName.

Функция 'build in', которую вы можете извлечь из вышеуказанного файла (она не закрыта). Начиная с версии 9.0 это выглядит так:

declare %private function json-custom:element-qname-from-json-name( $config as map:map , $json_name as xs:string? ) as xs:QName
{

   json-custom:qname( map:get( $config , $json-custom:element-namespace ) ,
                      map:get( $config , $json-custom:element-namespace-prefix ) ,
                      if(map:get($config , $json-custom:camel-case)) then  json-custom:from-camelCase($json_name) else $

 };

Это может быть очень сложно сделать правильно. Я рекомендую сочетание пользовательских преобразований с последующей постобработкой в ​​xml (используя xquery или xslt).

Сложность в том, что при переходе от JSON к XML вы не получаете большого «контекста». У JSON нет предков узлов или порядка. Все, что вы получаете, это одно имя поля. Если вы можете отобразить на желаемое QName из этого, то это легко. Например, вы можете создать карту имен json для QNames и поместить ее в конфигурацию вместе со своей пользовательской функцией.

Зачастую требования сложнее, поэтому рекомендуем вам просто попытаться «приблизиться» к конфигурации, а затем выполнить процесс.

...