2011-11-22 53 views
2

如何向PostgreSQL表示我希望在XPath查詢中同時從多個層次級別獲取值XPath查詢到分層數據中,保留祖先與後代的關係

我有一個文檔(在PostgreSQL的XML價值)與多層次的層次結構。對於這個問題,可以創建一個示例:

SELECT XMLPARSE(DOCUMENT ' 
    <parrots> 
     <parrot name="Fred"> 
      <descriptor>Beautiful plumage</descriptor> 
      <descriptor>Resting</descriptor> 
     </parrot> 
     <parrot name="Ethel"> 
      <descriptor>Pining for the fjords</descriptor> 
      <descriptor>Stunned</descriptor> 
     </parrot> 
    </parrots> 
    ') AS document 
INTO TEMPORARY TABLE parrot_xml; 

我可以從該文檔獲取不同級別的信息。

=> SELECT 
     (XPATH('./@name', parrot.node))[1] AS name 
    FROM (    
     SELECT 
      UNNEST(XPATH('./parrot', parrot_xml.document)) 
       AS node 
     FROM parrot_xml 
     ) AS parrot 
    ; 
name 
------- 
Fred 
Ethel 
(2 rows) 

=> SELECT 
     (XPATH('./text()', descriptor.node))[1] AS descriptor 
    FROM (
     SELECT 
      UNNEST(XPATH('./parrot/descriptor', parrot_xml.document)) 
       AS node 
     FROM parrot_xml 
     ) AS descriptor 
    ; 
     descriptor  
----------------------- 
Beautiful plumage 
Resting 
Pining for the fjords 
Stunned 
(4 rows) 

我想不出什麼,不過,是如何讓多個級別加入,使查詢返回其所適用的鸚鵡相關的每個描述符。

=> SELECT 
     ??? AS name, 
     ??? AS descriptor 
    FROM 
     ??? 
    ; 
name   descriptor  
------- ----------------------- 
Fred Beautiful plumage  
Fred Resting    
Ethel Pining for the fjords 
Ethel Stunned    
(4 rows) 

如何才能做到這一點?什麼應該去代替「???」?

一個複雜的XPath查詢 - 但是如何一次引用多個級別?幾個XPath查詢 - 但是如何保存結果關係的祖先 - 後代信息?還有別的嗎?

回答

4

試試這個:

SELECT (xpath('./@name', parrot.node))[1] AS name 
    , unnest(xpath('./descriptor/text()', parrot.node)) AS descriptor 
FROM (    
    SELECT unnest(xpath('./parrot', parrot_xml.document)) AS node 
    FROM parrot_xml 
    ) parrot; 

正好產生所需的輸出。

首先,在子查詢中,我檢索整個鸚鵡節點。每行一個節點。

接下來,我使用xpath()獲取名稱和描述符。兩者都是數組。我採用name的第一個(也是唯一)元素,並用'unnest()分割descriptor數組,從而達到期望的結果。我最近寫了comprehensive answer to a related question。可能會對你感興趣。

+0

非常好,但它也顯示了使用PostgreSQL處理XML的侷限性。嗯。帶有「選項的'xslt_process()'是完美的:-)。 –