Hadoop Hive XPaths 只返回数组的一部分



我正在使用Hadoop Hive并尝试处理XML文件。该文件如下所示:

<asds4_0:SASDS>
<stl15:GetRS>
<stl15:RS>
<stl15:ORES>
<stl15:ORE>
<stl15:AccF>
<stl15:Transaction>
<stl15:Status>Hold</stl15:Status>
</stl15:Transaction>
</stl15:AccF>
</stl15:ORE>
<stl15:ORE>
<stl15:AccF>
<stl15:Transaction>
<stl15:Status>Active</stl15:Status>
</stl15:Transaction>
</stl15:AccF>
</stl15:ORE>
</stl15:ORES>
</stl15:RS>
</stl15:GetRS>
</asds4_0:SASDS>

我用来检索状态的路径是:

SELECT
Status
FROM scenario1
LATERAL VIEW explode(xpath(cast(body as string),"//*[local-name()='SASDS']//*[local-name()='GetRS']//*[local-name()='RS']//*[local-name()='ORES']//*[local-name()='ORE']//*[local-name()='AccF']//*[local-name()='Transaction']//*[local-name()='Status']/text()")) adTable as Status

此 xpath 返回"活动"和"保持"两种状态。问题是我只想检索状态"活动"。 我尝试使用这样的东西[[local-name((='Status']='Active'](就像这里显示的那样 https://www.w3schools.com/xml/xpath_syntax.asp(我仍然得到两个记录持有和活动。

我不想在 sql 中使用 WHERE Status='Active',因为当我将其与其他字段组合在一起时,它不会返回所需的行。

首先,使用这样的结构有什么具体的原因吗?

*[local-name()='SASDS']

到处都是? 它等同于(但可读性较差(到

*:SASDS

此外,您可以在所有位置使用//*,这将返回并搜索所有后代元素。但是给定您的 XML 结构,您通常只想访问直接子级,因此使用/搜索子级更具可读性(且速度更快(。

因此,更好的做法是:

*:SASDS/*:GetRS/*:RS/*:ORES/*:ORE/*:AccF/*:Transaction/*:Status[. = "Active"]/text()

我喜欢Dirkk的解决方案,但是,正如您可能已经发现的那样,它不适合您。 Hive 中内置 XML 支持的众多限制之一是它基于 XPath 1.0。

但是,您可以将他的解决方案与Oracle XML Extensions for Hive一起使用: http://docs.oracle.com/bigdata/bda49/BDCUG/oxh_hive.htm#BDCUG691

它是Oracle XQuery for Hadoop的一部分,可以在这里下载: http://www.oracle.com/technetwork/database/database-technologies/bdc/big-data-connectors/downloads/index.html

例子:

SELECT xml_query_as_string(
"*:SASDS/*:GetRS/*:RS/*:ORES/*:ORE/*:AccF/*:Transaction/*:Status[. = 'Active']", 
body
) 
FROM scenario1;

将返回:"活动">

还有一个表格函数:

SELECT t.status
FROM scenario1 LATERAL VIEW xml_table(
'*:SASDS/*:GetRS/*:RS/*:ORES/*:ORE/*:AccF/*:Transaction', 
body, 
struct ('*:Status')
) t as status
WHERE t.status = 'Active';

如果你想放弃通配符,还有很好的命名空间支持:

SELECT t.status
FROM scenario1 LATERAL VIEW xml_table(
struct(
'stl15', 'http://example.org/ns1',
'asds4_0', 'http://example.org/ns2'
),
'asds4_0:SASDS/stl15:GetRS/stl15:RS/stl15:ORES/stl15:ORE/stl15:AccF/stl15:Transaction', 
body, 
struct ('stl15:Status')
) t as status
WHERE t.status = 'Active';

最新更新