下面是我的 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/