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

Posted

技术标签:

【中文标题】如何按属性从 XMLTYPE 字段中提取数据?【英文标题】:How do I extract data from an XMLTYPE field by attribute? 【发布时间】:2015-06-17 21:33:21 【问题描述】:

请原谅我完全是初学者。

我正在查看一个名为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;

并将所有FormObjectsEditValue 连接在一起。是否可以只过滤掉EditValue 所在的Label="Physical exam"

【问题讨论】:

【参考方案1】:

您可以使用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

【讨论】:

你是最棒的。谢谢!【参考方案2】:

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

/Form/FormObject/@EditValue 

【讨论】:

嘿,我有一个后续问题,需要一些帮助。有什么建议吗?

以上是关于如何按属性从 XMLTYPE 字段中提取数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何按名称从 plist 中提取数据?

使用 PL SQL 提取基于属性的 XML

arcgis在属性表里提取两个name

Oracle XMLType - 迭代具有某些属性值的元素

在arcgis中如何把通过属性选择的要素提取保存

arcgis无法构建栅格属性表的情况下,如何分级赋值