PostgreSQL 12中带text()表达式的xpath函数返回空集问题咨询
问题根因
PostgreSQL 12对xpath()函数的上下文处理逻辑做了不兼容调整:
- 9.6及更早版本:传入的XML元素会直接作为XPath表达式的上下文节点,所以
text()可以直接匹配到该元素下的文本内容 - 12及更高版本:传入的XML元素会被先包装到一个临时文档根节点下,XPath表达式的默认上下文是这个临时文档根节点,直接写
text()无法匹配到元素下的内容,因此返回空数组
适配方案
以下方案均满足「标签名未知、仅获取第一层节点内容、支持提取节点名/属性/文本」的业务要求:
方案1:修改XPath表达式匹配第一层子节点
把XPath表达式改为/*/text()即可,/*会匹配临时文档根下的第一层节点,也就是你传入的目标元素,不需要提前知道具体标签名:
SELECT xpath( '/*/text()', '<hl7_message_host _valuelabel="HL7 host">10.170.117.86</hl7_message_host>' );
返回结果和9.6版本完全一致:{10.170.117.86}
如果需要结合unnest()提取节点名、属性、文本,也可以直接适配:
SELECT unnest(xpath('name(/*)', xml_content)) AS node_name, unnest(xpath('/*/text()', xml_content)) AS node_text, unnest(xpath('/*/@_valuelabel', xml_content)) AS node_attr FROM (SELECT '<hl7_message_host _valuelabel="HL7 host">10.170.117.86</hl7_message_host>'::xml AS xml_content) t;
方案2:显式指定相对当前节点匹配
把XPath表达式改为./text(),显式声明从当前上下文节点开始匹配,效果和方案1一致:
SELECT xpath( './text()', '<hl7_message_host _valuelabel="HL7 host">10.170.117.86</hl7_message_host>' );
内容的提问来源于stack exchange,提问作者MadeR
相关产品推荐
相关产品推荐

