为带有属性字段的 NiFi 拆分处理器将 XML 转换为 Json

Converting XML to Json for NiFi Split Processor with Attribute fields

在 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 reader 推断模式,我会得到以下结果

{ "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控制器中,同样设置以下属性:

架构访问策略:“使用'Schema Text' 属性”

架构文本以上架构

期望记录为数组: true

内容字段名称:值

实现此目的的一种方法是创建与所需输出相匹配的第二个模式。然后使用 JoltTransformRecord 到 运行 的 Jolt 变换。你会想要像这样做一个 two-step:

Convert/SplitRecord -> JoltTransformRecord

此外,对于您所描述的用例,请使用 ConvertRecord 而不是 SplitRecord 除非您有大量记录并且只想将它们分开。如果您将记录拆分为 1 条记录,那将是一个非常低效的流程。 Record API 可以轻松处理从一次 1 条记录到几百万条记录的任何地方。