Marklogic json: конфигурация генерирует "_children" - PullRequest
0 голосов
/ 03 апреля 2019

Я не понимаю, почему Marklogic json: config генерирует "_children".Как я могу исключить "_children".Я вижу, что все перечисленные дети возвращаются за родителями, но в выводе JSON есть много лишнего мусора.

let $config := json:config("custom")
let $_ := map:put( $config, "full-element-names",xs:QName("Nav:keynavlist")

Вывод Json:

"Navigators": {
  "keynavlist": {
  "_children": [
     {
      "keynav": {
          "_value": "Fuel Cells"
      }
    }, 
 {
    "keynav": {
        "_value": "Microorganisms"
}
}, 
{
  "keynav": {
 "_value": "Waste Treatment"
}

Ответы [ 2 ]

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

Чтобы ответить на ваш первый вопрос

«Я не понимаю, почему Marklogic json: config генерирует« _children »

« Пользовательская »конфигурация предназначена для поддержки двунаправленный JSON <> преобразования XML, насколько это разумно. «Дополнительный мусор», на который вы ссылаетесь (например, _children), необходим для того, чтобы повернуть процесс вспять и создать исходный XML. «Базовая» стратегиядля простого преобразования в одну сторону из JSON в XML, а полная стратегия - для обратного (xml в JSON) - при сохранении максимально возможного количества информации .

Поскольку выперевод из XML в JSON, в котором любой элемент xml может иметь как атрибуты, так и дочерние элементы, а дочерние элементы могут иметь повторяющиеся имена, они не могут быть преобразованы в простой объект JSON без потери данных (в общем случае).

Стратегия «на заказ» обладает большой гибкостью (то есть «сложностью»), чтобы учесть тот факт, что «Мой случай» редко является «Общим случаем».'or "Your Case".

Одним из таких параметров конфигурации является возможность указывать xml qname, которые должны быть преобразованы в массивы вместо "_children" "array-element-names"

См.последний пример на этой странице: https://docs.marklogic.com/json:config

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

declare variable $doc :=   <a><b attr="d">c</b></a>;

let $c := json:config("custom") ,
    $_ := map:put( $c, "array-element-names", (xs:QName("a"),xs:QName("b")) ),
    $_ := map:put( $c, "attribute-names", ("attr" ) ), 
    $_ := map:put( $c, "text-value", "LABEL" ),
    $j := json:transform-to-json($doc ,$c ),
    $x := json:transform-from-json($j,$c) 
return ($j, $x)

(: The JSON property name "LABEL" is used to hold the text value from
    the element <b/>. Without the "text-value" option, the property name
    would be "_value". The query produces the following output: 

{"a":[{"b":[{"attr":"d", "LABEL":"c"}]}]}
<a><b attr="d">c</b></a> :)

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

Я считаю,Лучше всего мне подходит сочетание предварительной обработки, json: transform и post-processing.YMMV

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

Полагаю, вы хотели бы получить что-то вроде:

{
    "Navigators": {
        "keynavlist": [{
            "keynav": "Fuel Cells"
        }, {
            "keynav": "Microorganisms"
        }, {
            "keynav": "Waste Treatment"
        }]
    }
}

Но самое близкое, что вы можете получить с помощью библиотеки json transform, это:

{
    "Navigators": {
        "keynavlist": {
            "keynav": ["Fuel Cells", "Microorganisms", "Waste Treatment"]
        }
    }
}

Использование:

xquery version "1.0-ml";

import module namespace json="http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";

let $config := json:config("custom")
let $_ := map:put($config, "array-element-names", ("keynav"))
return json:transform-to-json(
  <Navigators>
    <keynavlist>
      <keynav>Fuel Cells</keynav>
      <keynav>Microorganisms</keynav>
      <keynav>Waste Treatment</keynav>
    </keynavlist>
  </Navigators>,
  $config
)

Рассмотрим создание json с рекурсивной функцией, может быть, что-то вроде этого:

declare function local:xml-to-json($nodes) {
  for $node in $nodes
  return typeswitch ($node)
    case element() return
      if ($node/attribute() or ($node/element() and $node/text())) then
        object-node {
          local-name($node): object-node {
            "@": array-node{ local:xml-to-json($node/attribute()) },
            "_": array-node { local:xml-to-json($node/node()) }
          }
        }
      else
        object-node {
          local-name($node): array-node{ local:xml-to-json($node/node()) }
        }
    case attribute() return
      object-node {
        local-name($node): data($node)
      }
    default return $node
};

local:xml-to-json(
  <Navigators>
    <keynavlist>
      <keynav>Fuel Cells</keynav>
      <keynav>Microorganisms</keynav>
      <keynav>Waste Treatment</keynav>
    </keynavlist>
  </Navigators>
)

НТН!

...