HiveQL - 提取Sibling节点的值

时间:2013-12-20 04:36:12

标签: xml xpath hadoop hive hiveql

我有一个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>

hive表中的每一行都有关于不同用户的信息,我想提取uid,名字和姓氏的值。

1424324325  John    Doe
1424435463  Jane    Smith

提取uid值非常简单。然而,我正在努力提取名字&amp;姓。问题在于识别名字和名字。姓氏对并提取值。

我试图提取名字&amp;姓氏如下所示,但我收到一个错误,说这是一个无效的表达。

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;

我想过为字段节点使用硬编码表达式,如下所示,但问题是不同的记录将在不同的位置具有名字和姓氏值。

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

提前致谢。

1 个答案:

答案 0 :(得分:1)

以下XPath应该能够为您提供正确的结果。您的语法不正确(谓词(即括号中的所有内容)都需要与元素一起使用,但您只是使用/执行了子步骤。

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

此外,还有一些要点可以改善您的查询:

  • 在比较节点值时,您不必使用text(),它将自动完成并且很可能更快
  • 您几乎总是希望string()使用text()
  • 我重写了查询,我认为这更简单,更清晰,因为它基本上说“给我一个值节点,它的名称节点的值为 first ”。您使用后续兄弟或父母的尝试也是有效的,我只是认为这个更容易阅读。