hiveql-提取同级节点的值

kuhbmx9i  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(319)

我在配置单元日志表中存储了一个xml blob(如下所示)。

<user>
    <uid>1424324325</uid>
    <attribs>
        <field>
        ...
        </field>
        <field>
            <name>first</name>
            <value>John</value>
        </field>
        <field>
        ...
        </field>
        <field>
            <name>last</name>
            <value>Doe</value>
        </field>
        <field>
        ...
        </field>
    </attribs>
</user>

配置单元表中的每一行都有关于不同用户的信息,我想提取uid、first name和last name的值。

1424324325  John    Doe
1424435463  Jane    Smith

提取uid值非常简单。然而,我被难倒试图提取的名字和姓氏。问题在于识别名字和姓氏对并提取值。
我试图提取名字和姓氏,如下所示,但我得到一个错误,说这是一个无效的表达式。

SELECT uid, fn, ln
FROM log_table
LATERAL VIEW explode(xpath(logs['users_updates'], '/user/uid/text()')) uids as uid
LATERAL VIEW explode(xpath(logs['users_updates'], '/user/attribs/field/name/text()="first"/../value/text()')) fns as fn
LATERAL VIEW explode(xpath(logs['users_updates'], '/user/attribs/field/name/text()="last"/../value/text()')) lns as ln;

我曾想过对field节点使用一个硬编码表达式,如下所示,但问题是不同的记录在不同的位置会有first name和last name值。

LATERAL VIEW explode(xpath(logs['users_updates'], '/user/attribs/field[5]/value/text()')) fns as fn

当我尝试按如下所示提取名字时,结果是空的。

LATERAL VIEW explode(xpath(logs['users_updates'], '/users/attribs/field/name/[text()="last"]/following-sibling::value[1]/text()')) fns as fn

我怎样才能提取我想要的信息如下?

1424324325  John    Doe
1424435463  Jane    Smith

提前谢谢。

7dl7o3gd

7dl7o3gd1#

下面的xpath应该为您提供正确的结果。您的语法不正确( predicate (即括号中的所有内容)需要包含元素,但您只是使用 / ).

/users/attribs/field[name = "first"]/value/string()

此外,还需要改进您的查询:
你不必使用 text() 当比较节点值时,它将自动完成,而且速度很可能更快
你几乎总是想用 string() 结束 text() 我重写了这个查询,我认为这更简单更干净,因为它基本上是说“给我值节点,它有一个名称节点,值在第一位”。你尝试使用下面的兄弟姐妹或父母也是有效的,我只是觉得这一个更容易阅读。

相关问题