Oracle XMLType - 迭代具有某些属性值的元素
Posted
技术标签:
【中文标题】Oracle XMLType - 迭代具有某些属性值的元素【英文标题】:Oracle XMLType - iterating over elements with certain attribute values 【发布时间】:2015-07-01 09:27:28 【问题描述】:我在 Oracle 数据库的一个字段中存储了以下 xml:
Activity mc:Ignorable="sap sap2010 sads" x:Class="Process"
xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities"
xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:awaw="clr-namespace:A.Workflow.Activities.WSCall;assembly=A.Workflow.Activities"
xmlns:awd="clr-namespace:A.Workflow.DataObjects;assembly=A.Workflow.DataObjects"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities"
xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger"
xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation"
xmlns:sap2010="http://schemas.microsoft.com/netfx/2010/xaml/activities/presentation"
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
xmlns:sco="clr-namespace:System.Collections.ObjectModel;assembly=mscorlib"
xmlns:sd="clr-namespace:System.Data;assembly=System.Data"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Members
x:Property Name="GlobalMessagesCollectionIn" Type="InArgument(awd:GlobalMessagesCollection)" />
x:Property Name="EventDataCollectionIn" Type="InArgument(awd:DataFileCollection)" />
x:Property Name="DocumentDataCollectionIn" Type="InArgument (awd:DataFileCollection)" />
x:Property Name="ResultDataCollectionIn" Type="InArgument (awd:DataFileCollection)" />
x:Property Name="BrokerRefIn" Type="InArgument(x:String)" />
x:Property Name="ClientFeeRefIn" Type="InArgument(x:String)" />
x:Property Name="InitUserTeamRefIn" Type="InArgument(x:String)" />
x:Property Name="InitUserTeamNameIn" Type="InArgument(x:String)" />
x:Property Name="InitUserBrokOffRefIn" Type="InArgument(x:String)" />
/x:Members>
mva:VisualBasic.Settings>
<x:Null />
/mva:VisualBasic.Settings>
/Activity
我正在尝试编写 pl/sql 过程 - 假设为每个 x:Property 元素输出 @Name 属性值,其中 Name 属性包含子字符串 'In'。
以下是我解决问题的尝试:
declare
p_ProcessFile xmltype;
BEGIN
SELECT ProcessFile
INTO p_ProcessFile
FROM Process
WHERE ProcessSeqNo = 4034; --This fetches the above xml into xmltype var
FOR i IN (select p_ProcessFile.extract( '//x:Members/x:Property[(contains(@Name, "In")) ]/@Name', 'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"').getStringVal() AS testing FROM dual) LOOP
dbms_output.put_line(i.testing || ';');
END LOOP;
END;
不幸的是,这会输出所有连接的值:
GlobalMessagesCollectionInEventDataCollectionInDocumentDataCollectionInResultDataCollectionInBrokerRefIn;
但是,我想要的是:
GlobalMessagesCollectionIn
EventDataCollectionIn
DocumentDataCollectionIn
ResultDataCollectionIn
etc
如何使用包含“In”的@Name 属性对每个 x:Property 进行迭代?
【问题讨论】:
【参考方案1】:也许值得注意的是 XMLSEQUNCE
已被弃用。
您可以在纯 SQL 中获得相同的结果 - 无需 PL/SQL 块或循环 - 使用 XMLTABLE
:
select x.name
from process p
cross join xmltable(
xmlnamespaces('http://schemas.microsoft.com/winfx/2006/xaml' as "x"),
'//x:Property[(contains(@Name, "In"))]'
passing p.processfile
columns name varchar2(30) path '@Name'
) x
where p.processseqno = 4034;
NAME
------------------------------
GlobalMessagesCollectionIn
EventDataCollectionIn
DocumentDataCollectionIn
ResultDataCollectionIn
BrokerRefIn
ClientFeeRefIn
InitUserTeamRefIn
InitUserTeamNameIn
InitUserBrokOffRefIn
【讨论】:
【参考方案2】:XML序列。用这个替换你的 for 循环。
for i in ( SELECT VALUE(p).extract('//x:Property[(contains(@Name, "In"))]/@Name', 'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"').getStringVal() val
FROM TABLE(XMLSEQUENCE(EXTRACT(p_ProcessFile, '//x:Members/x:Property[(contains(@Name, "In"))]', 'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'))) p ) loop
dbms_output.put_line(i.val);
end loop;
【讨论】:
谢谢你的救星。那么,它是否有效,因为 XMLSequence 将所有元素转换为“单独的”xml 文档数组?以上是关于Oracle XMLType - 迭代具有某些属性值的元素的主要内容,如果未能解决你的问题,请参考以下文章
如何在 oracle XMLTYPE XMLTABLE 中支持 1 级路径目录
oracle, xmltype/clob substr 循环