首页 > 解决方案 > 我如何从 xml 获取 CDATA 值

问题描述

谢谢点击,

  1. 我需要 CDATA 的价值

  2. 如果我想找到一个叫 Maria 并且她的生日是 2012-03-12 的人,我该如何找到它?

SELECT t.doc.extract('/RESPONSE/INFO/STU_NAME/text()').getStringVal()
"stu"
FROM table t
WHERE  t.doc.extract('/RESPONSE/INFO/STU_NAME/text()').getStringVal()
LIKE '%M%'

我试过了,但你看到下面是结果

<![CDATA[玛丽亚]]>

我不需要 <![CDATA[]]>

// XML
<STUDENT>
<INFO>
  <STU_NAME><![CDATA[ Maria ]]></STU_NAME>
  <STU_WARN><![CDATA[ one ]]></STU_WARN>
  <BIRTHDAY><![CDATA[ 2012-03-12 ]]></BRITHDAY>
</INFO>
<INFO>
  <STU_NAME><![CDATA[ Kevin) ]]></STU_NAME>
  <STU_WARN><![CDATA[ one ]]></STU_WARN>
  <BIRTHDAY><![CDATA[ 2010-07-15 ]]></BRITHDAY>
</INFO>

标签: sqlxmloraclesqlpluscdata

解决方案


extract 函数已被弃用很长时间(至少从11gR2开始- 请参阅该文档中的注释)。

如果您有多个值并且可能希望查看多个值,则可以使用 XMLTable,它可以消除 CDATA 噪音(但可能需要修剪,因为值中有空格):

select x.stu_name, x.birthday,
  trim(stu_name) as stu_name2, to_char(x.birthday,'YYYY-MM-DD') as birthday2
from your_table t
cross join xmltable ('/RESPONSE/INFO' passing t.doc
  columns
    stu_name varchar2(30) path 'STU_NAME',
    birthday date path 'BIRTHDAY'
) x
where x.stu_name like '%M%'
STU_NAME BIRTHDAY  STU_NAME2 BIRTHDAY2
-------- --------- --------- ---------
 Maria   12-MAR-12 Maria     2012-03-12

如果您针对单个值,您还可以使用更接近您的提取的 xmlquery:

select regexp_replace(
  xmlquery('/RESPONSE/INFO[contains(BIRTHDAY, "2012-03-12")]/STU_NAME/text()'
    passing doc
    returning content),
  '<!\[CDATA\[ *(.*?) *\]\]>', '\1') as stu_name
from your_table t
STU_NAME
--------
Maria

这是我在节点中以文本形式查找您想要的生日,并获得了匹配的名称;但由于它仍然有 CDATA 它与你所拥有的大致相同。因此,我使用了正则表达式来去除 CDATA 部分,但如果性能是一个问题,您也可以使用 substr/instr。

db<>小提琴


推荐阅读