首页 > 解决方案 > 在 PostgreSQL 中使用 XPath 过滤多个 XML 节点

问题描述

有一个 XML 的结构:

- Item
  - Documents
    - Document
      - Records
        - Record
          - Category
            - Code
          - Value

这是选择按类别代码过滤的记录值的 SQL 查询

SELECT  (xpath('/ns:Record/ns:Value/text()', rec, ARRAY[ARRAY['ns', 'http://some-ns']]))[1]::text AS val
FROM    (
    SELECT  unnest(xpath('/ns:Item/ns:Documents/ns:Document/ns:Records/ns:Record[ns:Category/ns:Code/text()="MAIN.CAT001"]',
               '<Item xmlns="http://some-ns"><Documents><Document><Records><Record><Category><Code>MAIN.CAT001</Code></Category><Value>Value 001</Value></Record><Record><Category><Code>MAIN.CAT002</Code></Category><Value>Value 002</Value></Record><Record><Category><Code>MAIN.CAT003</Code></Category><Value>Value 003</Value></Record></Records></Document></Documents></Item>'::xml,
               ARRAY[ARRAY['ns', 'http://some-ns']])) AS rec
) t

是否可以不仅按一个“类别代码”过滤“记录”,还可以按多个“类别代码”过滤“记录”?我的意思是我想使用这样的过滤器

ns:Record[ns:Category/ns:Code/text()=("MAIN.CAT001", "MAIN.CAT003")]

或这个

ns:Record[ns:Category/ns:Code/text()="MAIN.CAT001" or ns:Category/ns:Code/text()="MAIN.CAT003"]

但是两种解决方案都不起作用

标签: sqlxmlpostgresqlxpath

解决方案


尝试使用contains(ns:Code,"MAIN.CAT001") or contains(ns:Code,"MAIN.CAT003")]

SELECT  (xpath('/ns:Record/ns:Value/text()', rec, ARRAY[ARRAY['ns', 'http://some-ns']]))[1]::text AS val
FROM    (
  SELECT
    unnest(xpath('/ns:Item/ns:Documents/ns:Document/ns:Records/ns:Record[ns:Category[contains(ns:Code,"MAIN.CAT001") or contains(ns:Code,"MAIN.CAT003")]]',
                 '<Item xmlns="http://some-ns"><Documents><Document><Records><Record><Category><Code>MAIN.CAT001</Code></Category><Value>Value 001</Value></Record><Record><Category><Code>MAIN.CAT002</Code></Category><Value>Value 002</Value></Record><Record><Category><Code>MAIN.CAT003</Code></Category><Value>Value 003</Value></Record></Records></Document></Documents></Item>'::xml,
                 ARRAY[ARRAY['ns', 'http://some-ns']])) AS rec
) t;

    val    
-----------
 Value 001
 Value 003

推荐阅读