postgresql - 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 有什么问题?
解决方案
由于两个问题,您的第二个 xpath() 没有返回任何内容。首先:您需要使用//tCatSnVsn_Pmax
asxml_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
推荐阅读
- reactjs - 呃!运行反应项目时代码ELIFECYCLE errno 1
- excel - Microsoft Excel 2016 Unicode (UTF-8) 不起作用
- jquery - 基于选择jQuery动态更改iframe的DIV类
- sql - 验证 6 位数字和逗号的 NVARCHAR
- azure-stream-analytics - Azure 输入事件提前到达
- scala - Scala,猫 - 如何使用 IO(或其他 monad)和 Either 创建无标记的最终实现?
- javascript - 我的组件(应用程序)不呈现来自子组件的输入(InputForm)
- angular - ngIf-block 中可观察到的角度 rxjs 错过了第一次更新
- kubernetes - 如何将用户凭据传递到 Kubernetes Pod 内的(用户受限的)挂载卷?
- c# - 当消息传入使用 AES 加密时,我需要从 NetworkStream 读取多少字节?