2017-07-27 100 views
0

我正在使用Hadoop Hive并尝试处理XML文件。该文件是这样的:Hadoop Hive XPath只返回数组的一部分

<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> 

中的XPath我使用检索状态为:

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返回二者的状态主动和保持。问题是我只想检索Active状态。 我尝试使用这样的[[local-name()='Status'] ='Active'](就像这里显示的https://www.w3schools.com/xml/xpath_syntax.asp)我仍然得到两个记录保持和活动。

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

+0

强制性的评论:https://meta.stackoverflow.com/questions/280478 /为什么 - 不W3Schools的-COM – dirkk

回答

0

首先,有没有什么具体的理由,为什么你使用像

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

构建所有的地方?它相当于(但这样的可读性),以

*:SASDS 

此外,您使用//*无处不在,返回和所有子孙元素搜索。但是考虑到你的XML结构,你通常只想访问直接孩子,所以它再次更易读(更快),只需使用/来搜索孩子。

所以,更好的方式是:

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

我喜欢Dirkk的解决方案,但是,正如你可能已经发现了,它不会为你工作。 Hive内置XML支持的许多限制之一是它基于XPath 1.0。

但是,你可以用他与蜂巢在Oracle XML扩展的解决方案: http://docs.oracle.com/bigdata/bda49/BDCUG/oxh_hive.htm#BDCUG691

这是Oracle的XQuery 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'; 
你的资源