如何将含Array of Maps结构的指定XML转换为Hive表?
如何将嵌套XML转换为支持Array of Maps结构的Hive表
我来一步步教你实现这个需求,这在处理半结构化XML数据导入Hive时是很常见的场景。我们会用到Hive的XML SerDe来解析原始XML,再通过内置函数把结构化数据转成Array of Maps的格式。
步骤1:准备XML SerDe依赖
Hive原生没有自带XML解析的SerDe,我们需要用到com.ibm.spss.hive.serde2.xml.XmlSerDe。如果你的Hive集群还没有这个Jar包,先通过以下命令添加(Jar包路径根据你的实际部署调整):
ADD JAR /opt/cloudera/parcels/CDH/lib/hive/lib/hivexmlserde.jar;
步骤2:创建原始XML解析表
首先创建一个外部表,用来解析XML的顶层字段和嵌套节点。假设你的XML根节点是<TAG>,且<VERIF_ANSWERS>是重复的节点(对应数组),表结构定义如下:
CREATE EXTERNAL TABLE xml_raw_data ( request_id STRING, application_id STRING, external_system_code STRING, ccm_check STRUCT<ccm_check_id:STRING, ccm_check_result:STRING>, verif_answers ARRAY<STRUCT<check_code:STRING, question_code:STRING, bookmark_number:STRING, answer_value:STRING>> ) ROW FORMAT SERDE 'com.ibm.spss.hive.serde2.xml.XmlSerDe' WITH SERDEPROPERTIES ( "xml.tag"="TAG", -- 指定XML根节点 "xpath.request_id"="/TAG/REQUEST_ID/text()", -- 顶层字段的XPath "xpath.application_id"="/TAG/APPLICATION_ID/text()", "xpath.external_system_code"="/TAG/EXTERNAL_SYSTEM_CODE/text()", "xpath.ccm_check"="/TAG/CCM_CHECK", -- 单个嵌套节点的XPath "xpath.verif_answers"="/TAG/VERIF_ANSWERS" -- 数组节点的XPath ) LOCATION '/user/hive/xml_data/'; -- XML文件存储的HDFS路径
步骤3:转换为Array of Maps结构
接下来我们创建目标表,把解析后的STRUCT类型转换成Map,再把重复的VERIF_ANSWERS节点转成Array of Maps。这里用到Hive的map()和transform()函数,后者可以直接对数组中的每个元素做转换:
CREATE TABLE target_array_map_table AS SELECT request_id, application_id, external_system_code, -- 将单个CCM_CHECK的STRUCT转为Map map( 'ccm_check_id', ccm_check.ccm_check_id, 'ccm_check_result', ccm_check.ccm_check_result ) AS ccm_check_map, -- 将VERIF_ANSWERS数组中的每个STRUCT转为Map,生成Array of Maps transform(verif_answers, va -> map( 'check_code', va.check_code, 'question_code', va.question_code, 'bookmark_number', va.bookmark_number, 'answer_value', va.answer_value ) ) AS verif_answers_array FROM xml_raw_data;
关键细节说明
- 如果你的XML中
<CCM_CHECK>也是多个重复节点,只需把原始表中的ccm_check定义为ARRAY<STRUCT>,再用同样的transform()函数转成Array of Maps即可。 - 若存在字段为空的情况,可以用
coalesce()函数处理null值,比如coalesce(va.check_code, '')避免Map中出现null值。 - 确保XPath路径和XML节点名称完全匹配(区分大小写),否则会解析失败。
内容的提问来源于stack exchange,提问作者gjin
相关产品推荐
相关产品推荐

