2017-07-27 16 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'; 
你的資源