PostgreSQL绝对超过相对xpath位置

时间:2020-07-15 11:12:58

标签: postgresql xpath

考虑以下存储在PostgreSQL字段中的xml文档:

 <E_sProcedure xmlns="http://www.minushabens.com/2008/FMSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" modelCodeScheme="Emo_ex" modelCodeSchemeVersion="01" modelCodeValue="EMO_E_PROCEDURA" modelCodeMeaning="Section" sectionID="11">
        <tCatSnVsn_Pmax modelCodeScheme="Emodinamica_referto" modelCodeSchemeVersion="01" modelCodeValue="tCat4" modelCodeMeaning="My text"><![CDATA[1]]></tCatSnVsn_Pmax>
</E_sProcedure>

如果我运行以下查询,我将获得第1行的正确结果,而第2行则不返回任何内容:

SELECT
--Line 1
TRIM(BOTH FROM array_to_string((xpath('//child::*[@modelCodeValue="tCat4"]/text()', t.xml_element)),'')) as tCatSnVsn_Pmax_MEANING
--Line2
,TRIM(BOTH FROM array_to_string((xpath('/tCatSnVsn_Pmax/text()', t.xml_element)),'')) as tCatSnVsn_Pmax
FROM (
    SELECT unnest(xpath('//x:E_sProcedure', s.XMLDATA::xml, ARRAY[ARRAY['x', 'http://www.minushabens.com/2008/FMSchema']])) AS xml_element
    FROM sr_data as s)t;

第2行的xpath有什么问题?

1 个答案:

答案 0 :(得分:2)

由于两个问题,您的第二个xpath()不返回任何内容。首先:您需要使用//tCatSnVsn_Pmax,因为xml_element仍以<E_sProcedure>开头。路径/tCatSnVsn_Pmax尝试选择具有该名称的顶级元素。

但是即使那样,由于名称空间,第二个也不会返回任何内容。您需要将相同的名称空间定义传递给xpath(),因此需要这样的内容:

SELECT (xpath('/x:tCatSnVsn_Pmax/text()', t.xml_element, ARRAY[ARRAY['x', 'http://www.minushabens.com/2008/FMSchema']]))[1] as tCatSnVsn_Pmax
FROM (
    SELECT unnest(xpath('//x:E_sProcedure', s.XMLDATA::xml, ARRAY[ARRAY['x', 'http://www.minushabens.com/2008/FMSchema']])) AS xml_element
    FROM sr_data as s
)t;

对于现代Postgres版本(> = 10),我更喜欢将xmltable()用于任何无关紧要的事情。它使传递名称空间更加容易,并可以访问多个属性或元素。

SELECT xt.*
FROM sr_data
  cross join 
      xmltable(xmlnamespaces ('http://www.minushabens.com/2008/FMSchema' as x),
               '/x:E_sProcedure'
               passing (xmldata::xml)
               columns 
                  sectionid text path '@sectionID', 
                  pmax text path 'x:tCatSnVsn_Pmax',
                  model_code_value text path 'x:tCatSnVsn_Pmax/@modelCodeValue') as xt

对于您的示例XML,以上返回:

sectionid | pmax | model_code_value
----------+------+-----------------
11        | 1    | tCat4