XPath查询分层数据,保留祖先 - 后代关系

时间:2011-11-22 00:02:26

标签: xml postgresql xpath

我如何向PostgreSQL表达我希望从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)

但我无法弄清楚的是如何连接多个级别,以便查询返回与其应用的parrot相关的每个描述符。

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

如何做到这一点?什么应该代替“???”?

单个复杂的XPath查询 - 但如何一次引用多个级别?几个XPath查询 - 但是后来如何为结果关系保留祖先后代信息?还有别的吗?

1 个答案:

答案 0 :(得分: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的第一个(也是唯一的)元素并将descriptor数组拆分为`unnest(),从而得到所需的结果。

我最近写了comprehensive answer to a related question。您可能会感兴趣。