Преобразование XML в Json для разделенного процессора NiFi с полями атрибутов

#json #xml #schema #apache-nifi

#json #xml #схема #apache-nifi

Вопрос:

В NiFi я пытаюсь использовать процессор SplitRecord для преобразования входящих XML-файлов в Json.

Структура XML-файла выглядит следующим образом:

 <?xml version="1.0" encoding="UTF-8"?>
<docs>
   <doc boost="1.0">
      <field name="id">12345</field>
      <field name="name">john smith</field>
      <field name="age">34</field>
   </doc>
   <doc boost="1.0">
      <field name="id">74832</field>
      <field name="name">jane doe</field>
      <field name="age">16</field>
   </doc>
   <doc boost="1.0">
      <field name="id">08423</field>
      <field name="name">henry jones</field>
      <field name="age">29</field>
   </doc>
</docs>
  

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

Прямо сейчас в процессоре SplitRecord я использую контроллер XmlReader и контроллер JSONsetrecordWriter. Если я просто позволю считывателю XML вывести схему, я получу следующий результат

 { "doc": [ {
    "field" : ["12345", "john smith", "34"]
    },
    {
    "field" : ["74832", "jane doe", "16"]
    },
    {
    "field" : ["08423", "henry jones", "29"]
    } ]
}
  

Вы можете видеть, что все поля потеряли свои метаданные, я хочу что-то ближе к этому:

 { 
"id":"12345",
"name":"john smith",
"age":"34"
},
{ 
"id":"74832",
"name":"jane doe",
"age":"16"
},
{ 
"id":"08423",
"name":"henry jones",
"age":"29"
}
  

В контроллере XmlReader, если я переключусь на использование свойства «Текст схемы», и в поле свойства текста схемы я помещаю эту схему:

 {
  "type" : "record",
  "name" : "docs",
  "namespace" : "doc",
  "fields" : [ {
    "name" : "boost", "type" : "string"
  }, 
  {
    "name" : "field",
    "type" : {
        "type" : "array",
            "items" : {
              "type" : "record",
              "name" : "field",
              "namespace" : "name",
              "fields" : [ 
              {"name" : "id","type": "string"},
              {"name":"name","type":"string"},
              {"name":"age","type":"string"}
              ]
            }
    }
  }
  ]
}
  

Я не получаю результата, на самом деле результат теперь такой:

 {"boost":null,"field":[]}
  

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

Обновить

Я определил свою рабочую схему

 {
  "name": "docs",
  "namespace": "doc",
  "type": "record",
  "fields": [
      {
         "name" : "field",
         "type" : {
         "type" : "array",
            "items" : {
              "type" : "record",
              "name" : "field",
              "namespace" : "name",
              "fields" : [ 
                          {"name": "name", "type": "string"},
                          {"name": "value", "type": "string"}
                         ]
                      }
                  }
       }
     ]
}
  

в контроллере xmlreader также задайте следующие свойства:

Стратегия доступа к схеме: «Использовать свойство «Текст схемы»»

Текст схемы: приведенная выше схема

Ожидайте записи в виде массива: true

Имя поля для содержимого: значение

Ответ №1:

Один из способов добиться этого — создать вторую схему, соответствующую вашему желаемому результату. Затем используйте JoltTransformRecord для запуска преобразования Jolt. Для этого вам нужно выполнить два шага следующим образом:

Convert/SplitRecord -> JoltTransformRecord

Кроме того, для описанного вами варианта использования используйте ConvertRecord вместо SplitRecord , если у вас МНОГО записей и вы просто хотите разделить вещи. Если вы разбиваете записи до 1 записи на фрагмент, это очень неэффективный процесс. API записей может легко обрабатывать от 1 записи за раз до нескольких миллионов записей.

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

1. спасибо @Mike Thomsen, я воспользуюсь вашей заметкой, чтобы использовать ConvertRecord вместо этого. Итак, я понял из того, что вы говорите, что невозможно перейти прямо из XML в JSON в желаемом формате с использованием схемы, мне также понадобится JoltTransformRecord?

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

3. Исправьте необходимость второго шага. Convert / SplitRecord не может преобразовать запись до такой степени за один шаг, потому что они не предназначены для этого.