如何按属性从XMLTYPE字段提取数据?

时间:2015-06-17 21:33:21

标签: sql xml oracle plsql

原谅我是一个初学者。

我正在查看名为FORM_XML的列,该列被描述为数据类型XMLTYPE一个字段的内容为:

<Form FormID="0" Name="Preventive Care(F)">
  <FormObject Name="prevcare01" Type="DateTime" Label="Physical Exam" EditValue="04/05/2007" />
  <FormObject Name="prevcare02" Type="DateTime" Label="Lipid Profile" EditValue="NoEditValue" />
  <FormObject Name="prevcare03" Type="DateTime" Label="Health Care Proxy review" EditValue="NoEditValue" />
  <FormObject Name="prevcarecomm" Type="Text" Label="Comments" EditValue="NoEditValue" />
</Form>

目标是提取EditValue日期Label="Physical exam"。在此示例中,日期04/05/2007是我想要提取的内容。是否有可以实现此目的的神奇查询?

现有的问题没有帮助,因为他们的XML数据结构不同。我的XML数据是否构造错误,因为它不包含名称空间和特定标签?

后续问题: 我跑了

SELECT Extract(form_xml, '/Form/FormObject/@EditValue') FROM patient_form;

将所有EditValue连接在一起FormObjects。是否可以过滤EditValue Label="Physical exam"

2 个答案:

答案 0 :(得分:2)

您可以使用XMLTABLE将XML转换为行和列,然后应用过滤器。

查询:

SQL> with x(y) as (
  select xmltype('<Form FormID="0" Name="Preventive Care(F)">
  <FormObject Name="prevcare01" Type="DateTime" Label="Physical Exam" EditValue="04/05/2007" />
  <FormObject Name="prevcare02" Type="DateTime" Label="Lipid Profile" EditValue="NoEditValue" />
  <FormObject Name="prevcare03" Type="DateTime" Label="Health Care Proxy review" EditValue="NoEditValue" />
  <FormObject Name="prevcarecomm" Type="Text" Label="Comments" EditValue="NoEditValue" />
</Form>') from dual
  )
select z.*
from x cross join
xmltable('Form/FormObject' passing x.y
         columns label_ varchar2(30) path '@Label',
                 editvalue_ varchar2(30) path '@EditValue'
         ) z
where z.label_ = 'Physical Exam';

结果:

LABEL_                         EDITVALUE_
------------------------------ ------------------------------
Physical Exam                  04/05/2007

或者在转换为行和列之前使用XQuery对其进行过滤。

查询:

SQL> with x(y) as (
  select xmltype('<Form FormID="0" Name="Preventive Care(F)">
  <FormObject Name="prevcare01" Type="DateTime" Label="Physical Exam" EditValue="04/05/2007" />
  <FormObject Name="prevcare02" Type="DateTime" Label="Lipid Profile" EditValue="NoEditValue" />
  <FormObject Name="prevcare03" Type="DateTime" Label="Health Care Proxy review" EditValue="NoEditValue" />
  <FormObject Name="prevcarecomm" Type="Text" Label="Comments" EditValue="NoEditValue" />
</Form>') from dual
  )
select z.*
from x cross join
xmltable('for $i in /Form/FormObject
                where $i/@Label = "Physical Exam"
                return $i' passing x.y
         columns label_ varchar2(30) path '@Label',
                 editvalue_ varchar2(30) path '@EditValue'
         ) z;

结果:

LABEL_                         EDITVALUE_
------------------------------ ------------------------------
Physical Exam                  04/05/2007

答案 1 :(得分:0)

命名空间通常是使生活变得复杂的原因,没有命名空间应该更简单。

/Form/FormObject/@EditValue