hadoop—使用xpath将xml节点提取到配置单元表中

y53ybaqx  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(411)

我们有一个配置单元表,其中一个字符串列包含xml。为了简化,假设该表为:

DataTable
key: string
xml: string

xml的格式是:

<xml>
    <entity>
        <property type="alpha">123</property>
        <property type="beta">abc</property>
        <property type="delta">...</property>
    </entity>
    <entity>
        <property type="alpha">321</property>
        <property type="beta">cba</property>
        <property type="delta">---</property>
    </entity>
</xml>

具有0..n个实体节点。
我想将此数据转换为以下格式的新配置单元表:

TransformedTable
key: string
alpha: string
beta: string
delta: string

但我觉得很难。我对Hive还很陌生,但我觉得这样的东西应该很合适。
以下问题相关:
使用pig解析配置单元表中的嵌套xml字符串
分析配置单元中的重复xml标记
但没有答案。这个问题有一个相关的答案:
在配置单元中使用侧视图时出现异常
但我不认为我可以在这种情况下使用xml服务器。通过这项研究,我试过这样的方法:

select key, 
       xpath(xml, 'xml/entity/property[@type="alpha"]/text()')) as alpha,
       xpath(xml, 'xml/entity/property[@type="beta"]/text()')) as beta,
       xpath(xml, 'xml/entity/property[@type="delta"]/text()')) as delta
  from DataTable

但结果是:

key1    ["123", "321"]    ["abc", "cba"]    ["...", "---"]
key2    ["123", "321"]    ["abc", "cba"]    ["...", "---"]

而不是我真正想要的:

key1    123    abc    ...
key1    321    cba    ---
key2    123    abc    ...
key2    321    cba    ---

谢谢你花时间阅读这篇文章,如果你能给我一些建议,我将不胜感激!

7bsow1i6

7bsow1i61#

基于数组的数据可以使用 LATERAL VIEW 结合表生成函数,例如 explode . 在这种情况下,另一个并发症是,我们需要3个单独的事件 LATERAL VIEW 对应于
alpha beta 以及 delta 数组,这会在结果集中产生完全笛卡尔积的风险;每个alpha/beta/delta排列将生成一个单独的行。
为了避免笛卡尔积,我们可以使用 posexplode ,它从原始数组生成数字索引和数据值。然后,我们可以使用过滤条件来确保只查看与原始数组中的位置匹配的行。
查询

WITH DataTable AS (
    SELECT 'key1' AS key, '<xml><entity><property type="alpha">123</property><property type="beta">abc</property><property type="delta">...</property></entity><entity><property type="alpha">321</property><property type="beta">cba</property><property type="delta">---</property></entity></xml>' AS xml UNION ALL
    SELECT 'key2' AS key, '<xml><entity><property type="alpha">123</property><property type="beta">abc</property><property type="delta">...</property></entity><entity><property type="alpha">321</property><property type="beta">cba</property><property type="delta">---</property></entity></xml>' AS xml
)
SELECT
    key,
    alpha,
    beta,
    delta
FROM DataTable
LATERAL VIEW posexplode(xpath(xml, 'xml/entity/property[@type="alpha"]/text()')) xml_alpha AS pos_alpha, alpha
LATERAL VIEW posexplode(xpath(xml, 'xml/entity/property[@type="beta"]/text()')) xml_beta AS pos_beta, beta
LATERAL VIEW posexplode(xpath(xml, 'xml/entity/property[@type="delta"]/text()')) xml_delta AS pos_delta, delta
WHERE pos_alpha = pos_beta
AND pos_beta = pos_delta
;

结果集

key alpha   beta    delta
0   key1    123 abc ...
1   key1    321 cba ---
2   key2    123 abc ...
3   key2    321 cba ---

如果需要进一步的定制,那么您可以考虑编写自己的定制udtf,以完全按照需要生成行。

相关问题