Hive中如何解析XML同一父节点下重复同标签并正确映射Name-Value对
问题根源定位
你之前的写法产生笛卡尔积的核心原因是:两个独立的XPATH提取逻辑是在整段XML的全局范围拉取数据:
- 第一次提取拿到全文档下所有Name值,组成列表
[ABCD, EFGH] - 第二次提取拿到全文档下所有Value值,组成列表
[111, 222, 333, 444, 555]
两个列表没有任何关联绑定关系,SQL引擎会自动做全量交叉连接,完全丢失了同一ParentFieldArray下的Name和Value配对的逻辑。
就算用POSEXPLODE拿到每个元素的全局位置序号,也没法准确匹配归属——因为每个父节点下的Value数量不固定,位置偏移是动态变化的,根本没法靠全局位置判断每个Value属于哪个Name。
正确实现思路
把处理粒度从“全局所有元素”下沉到单个ParentFieldArray父节点单元,每个单元单独做内部的Name、Value配对,从根源上避免跨节点的交叉连接:
- 第一步:先把每个独立的ParentFieldArray节点从整段XML中拆成单独的行,每行存储该父节点的完整XML片段
- 第二步:对每个父节点片段,提取它内部唯一的Name值
- 第三步:对同一个父节点片段,炸开它内部所有的Value文本,和当前片段的Name值做绑定
可直接运行的SQL实现
SELECT pf_name, pf_value FROM table_name -- 拆分每个独立ParentFieldArray节点为单独行 LATERAL VIEW EXPLODE( XPATH(xmlinfo, 'ParentArray/ParentFieldArray') ) AS t(parent_xml) -- 提取当前父节点下唯一的Name值 LATERAL VIEW EXPLODE( ARRAY(XPATH_STRING(parent_xml, 'ParentFieldArray/Name/text()')) ) AS n(pf_name) -- 炸开当前父节点下所有Value的string文本 LATERAL VIEW EXPLODE( XPATH(parent_xml, 'ParentFieldArray/Value/string/text()') ) AS v(pf_value) ;
实际输出效果
查询运行结果和预期完全一致:
| Name | Value |
|---|---|
| ABCD | 111 |
| ABCD | 222 |
| ABCD | 333 |
| EFGH | 444 |
| EFGH | 555 |
这种写法不需要手动计算位置偏移,自动适配不同父节点下Value数量不固定的场景,完全不会产生笛卡尔积。
内容的提问来源于stack exchange,提问作者RKR
相关产品推荐
相关产品推荐

