xml - 在 PostgreSQL 中提取 xml 标签的值

标签 xml postgresql xpath casting xml-parsing

下面是我的 Postgres 表的列响应。我想从我的 Postgres 数据库中的所有行中提取状态。状态也可能有不同的大小,例如 SUCCESS,所以我不想使用 substring 函数。有办法吗?

<?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status><responseType>COUNTRY_MISSING</responseType><country_info>USA</country_info><phone_country_code>1234</phone_country_code></response>

所以我的表结构是这样的

   Column    |            Type             |                        Modifiers                         

-------------+-----------------------------+----------------------------------------------------------

 id          | bigint                      | not null default nextval('events_id_seq'::regclass)
 hostname    | text                        | not null
 time        | timestamp without time zone | not null
 trn_type    | text                        | 
 db_ret_code | text                        | 
 request     | text                        | 
 response    | text                        | 
 wait_time   | text                        | 

我想从每个请求中提取状态。我该怎么做?

下面是一个示例行。并假定表名 abc_events

id          | 1870667
hostname    | abcd.local
time        | 2013-04-16 00:00:23.861
trn_type    | A
request     | <?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status><responseType>COUNTRY_MISSING</responseType><country_info>USA</country_info><phone_country_code>1234</phone_country_code></response>
response    | <?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status><responseType>COUNTRY_MISSING</responseType><country_info>USA</country_info><phone_country_code>1234</phone_country_code></response>

最佳答案

使用 xpath() 功能:

WITH x(col) AS (SELECT '<?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status></response>'::xml)
SELECT xpath('./status/text()', col) AS status
FROM   x

/text()剥离周围<status>标签。
返回 xml 的数组- 在这种情况下只有一个元素:

status
xml[]
-------
{ERROR_MISSING_DATA}

应用于你的表

针对您的问题更新,这可以简单地是:

SELECT id, xpath('./status/text()', response::xml) AS status
FROM   tbl;

如果您确定每行只有一个状态标签,您可以简单地从数组中提取第一项:

SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM   tbl;

如果可以有多个状态项:

SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM   tbl;

根据 id 获取 1-n 行.

转换为 xml

由于您将列定义为 text 类型(而不是 xml ,您需要显式转换为 xml。函数 xpath() 需要类型为 xml 的第二个参数。未类型化的字符串常量会自动强制转换为 xml ,但 text 不是。您需要显式转换。

这在没有显式转换的情况下有效:

  SELECT xpath('./status/text()'
      ,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')

CTE 就像我的第一个示例需要“公用表表达式”中每一列的类型。如果我没有转换为特定类型,则类型 unknown会被使用 - 这与 未键入的字符串 是一回事。显然,unknown 之间没有实现直接转换。和 xml .您必须转换为 text第一:unknown_type_col::text::xml .最好转换到 ::xml马上。

PostgreSQL 9.1(我认为)加强了这一点。旧版本更宽松。

无论哪种方式,对于这些方法中的任何一种,字符串都必须是有效的 xml,否则转换(隐式或显式)将引发异常。

关于xml - 在 PostgreSQL 中提取 xml 标签的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16023523/

相关文章:

sql - 如何使用 NHibernate 将 XML 类型列映射到强类型对象属性?

c# - 如何创建 Xml 文件并立即在 Windows-App C# 中打开它?

mysql - 求和返回字符串,仅适用于 postgresql

xml - 用于将属性值与集合进行匹配的 XPath 查询

html - 输入元素后标签的 XPath?

c# - 序列化 .net 对象并省略文档类型?

java - NoSuchFieldError : QUALIFIED when integrating web service in Tomcat project 错误

database - postgresql execParams paramTypes 是什么意思?

postgresql - JPA eclipselink OID 大对象 PostgreSQL

html - XSL重复相同的XML元素/节点,无法正常工作