Oracle XMLType - 迭代具有特定属性值的元素

时间:2015-07-01 09:27:29

标签: sql xml oracle plsql xmltype

我将以下xml存储在Oracle数据库的字段中:

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属性包含子字符串&#39; In&#39;。

以下是我尝试解决问题的方法:

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

如何迭代每个x:包含&#39; In&#39;?

的@Name属性的属性

2 个答案:

答案 0 :(得分:3)

也许值得注意的是,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          

答案 1 :(得分:2)

XMLSEQUENCE。用这个替换你的循环。

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;