使用XMLTYPE查找重复节点

时间:2014-06-27 12:06:05

标签: xml oracle xquery xmltype xmltable

我有这个代码,我想用它来获取重复的节点。到目前为止,我只设法对子字符串进行硬编码以从FirstName和Surname中找到一个值,其中Name类型为='Spelling Variation'。我的所有其他尝试都失败了,返回了各种错误和空值。有没有办法做到这一点,而不必提供[1],[2],[3],[?]。

非常感谢传递的任何信息。

--------------------------------------------------------------------------------------
declare
    x xmltype := xmltype('<?xml version="1.0" ?> 
    <Records>
     <Person id="34463" action="chg" date="23-Nov-2009">
       <Gender>Female</Gender> 
       <ActiveStatus>Inactive</ActiveStatus> 
       <Deceased>No</Deceased> 
       <NameDetails>
           <Name NameType="Primary Name">
               <NameValue>
                   <FirstName>34463FirstName</FirstName> 
                   <Surname>34463Surname</Surname> 
               </NameValue>
           </Name>
           <Name NameType="Spelling Variation">
               <NameValue>
                   <FirstName>34463FirstnameVar1</FirstName> 
                   <Surname>34463SurnameVar1</Surname> 
               </NameValue>
               <NameValue>
                   <FirstName>34463FirstNameVar2</FirstName> 
                   <Surname>34463SurnameVar2</Surname> 
               </NameValue>
           </Name>
       </NameDetails>
    </Person>
    <Person id="34464" action="chg" date="23-Nov-2009">
       <Gender>Male</Gender> 
       <ActiveStatus>Inactive</ActiveStatus> 
       <Deceased>No</Deceased> 
       <NameDetails>
           <Name NameType="Primary Name">
               <NameValue>
                   <FirstName>34464FirstName</FirstName> 
                   <Surname>34464Surname</Surname> 
               </NameValue>
           </Name>
           <Name NameType="Spelling Variation">
               <NameValue>
                   <FirstName>34464FirstnameVar1</FirstName> 
                   <Surname>34464SurnameVar1</Surname> 
               </NameValue>
               <NameValue>
                   <FirstName>34464FirstnameVar2</FirstName> 
                   <Surname>34464SurnameVar2</Surname> 
               </NameValue>
           </Name>
       </NameDetails>
     </Person>
   </Records>');

    begin

    for get_id in (select extractvalue(value(id),'/Person/@id') as id
                   from table(xmlsequence(extract(x,'/Records/Person'))) id ) loop

     --   dbms_output.put_line(get_id.id);

        for get_gender in (select extractvalue(value(gender),'/Person/Gender') as gender
                           from table(xmlsequence(extract(x,'/Records/Person'))) gender
                           where extractValue(value(gender),'/Person/@id') =get_id.id)     
    loop
            dbms_output.put_line(get_gender.gender);
        end loop;

       for get_name in (select extractvalue(value(fname),'/NameValue/FirstName') as fname
                         from table(xmlsequence(extract
        (x,'/Records/Person/NameDetails/Name/NameValue'))) fname
                         where extractValue(value(fname),'/Person/@id') = get_id.id) loop

            dbms_output.put_line('Name is '||get_name.fname);
        end loop;

      for get_name in
      (--Pick out primary name
         SELECT extractvalue(value(xname),'/Name/NameValue/FirstName') fname
               ,extractvalue(value(xname),'/Name/NameValue/Surname') sname
               ,extractvalue(value(xname),'/Name/NameValue/OriginalScriptName') oname
         FROM table(xmlsequence(extract(
            (--Get person TAG
            select xmltype(xperson.OBJECT_VALUE.getstringval() )
            from table(xmlsequence(extract(x,'/Records/Person'))) xperson
            where extractValue(value(xperson),'/Person/@id') = get_id.id
            )
           ,'Person/NameDetails/Name'))) xname
         WHERE extractValue(value(xname),'/Name/@NameType') in ('Primary Name')
      )
      loop
         dbms_output.put_line(get_name.fname||' '||get_name.sname||' '||get_name.oname);
         dbms_output.put_line(' ');
      end loop;


      for get_name in
      (--Pick out Spelling Variation
         SELECT extractvalue(value(xname),'/Name/NameValue[1]/FirstName') fname1
               ,extractvalue(value(xname),'/Name/NameValue[1]/Surname') sname1
               ,extractvalue(value(xname),'/Name/NameValue[2]/FirstName') fname2
               ,extractvalue(value(xname),'/Name/NameValue[2]/Surname') sname2
               ,extractvalue(value(xname),'/Name/NameValue[3]/FirstName') fname3
               ,extractvalue(value(xname),'/Name/NameValue[3]/Surname') sname3
              FROM table(xmlsequence(extract(
            (--Get person TAG
            select xmltype(xperson.OBJECT_VALUE.getstringval() )
            from table(xmlsequence(extract(x,'/Records/Person'))) xperson
            where extractValue(value(xperson),'/Person/@id') = get_id.id
            )
           ,'Person/NameDetails/Name'))) xname
         WHERE extractValue(value(xname),'/Name/@NameType') in ('Spelling Variation')
      )
      loop
         dbms_output.put_line(get_name.fname1||' '||get_name.sname1);
         dbms_output.put_line(get_name.fname2||' '||get_name.sname2);
         dbms_output.put_line(get_name.fname3||' '||get_name.sname3);
         dbms_output.put_line(' ');
      end loop;

         dbms_output.put_line(' ');
    end loop;

end;

1 个答案:

答案 0 :(得分:0)

declare
    x xmltype := xmltype('<?xml version="1.0" ?> 
    <Records>
     <Person id="34463" action="chg" date="23-Nov-2009">
       <Gender>Female</Gender> 
       <ActiveStatus>Inactive</ActiveStatus> 
       <Deceased>No</Deceased> 
       <NameDetails>
           <Name NameType="Primary Name">
               <NameValue>
                   <FirstName>34463FirstName</FirstName> 
                   <Surname>34463Surname</Surname> 
               </NameValue>
           </Name>
           <Name NameType="Spelling Variation">
               <NameValue>
                   <FirstName>34463FirstnameVar1</FirstName> 
                   <Surname>34463SurnameVar1</Surname> 
               </NameValue>
               <NameValue>
                   <FirstName>34463FirstNameVar2</FirstName> 
                   <Surname>34463SurnameVar2</Surname> 
               </NameValue>
           </Name>
       </NameDetails>
    </Person>
    <Person id="34464" action="chg" date="23-Nov-2009">
       <Gender>Male</Gender> 
       <ActiveStatus>Inactive</ActiveStatus> 
       <Deceased>No</Deceased> 
       <NameDetails>
           <Name NameType="Primary Name">
               <NameValue>
                   <FirstName>34464FirstName</FirstName> 
                   <Surname>34464Surname</Surname> 
               </NameValue>
           </Name>
           <Name NameType="Spelling Variation">
               <NameValue>
                   <FirstName>34464FirstnameVar1</FirstName> 
                   <Surname>34464SurnameVar1</Surname> 
               </NameValue>
               <NameValue>
                   <FirstName>34464FirstnameVar2</FirstName> 
                   <Surname>34464SurnameVar2</Surname> 
               </NameValue>
           </Name>
       </NameDetails>
     </Person>
   </Records>');

begin
    for get_id in (
        select *
        from xmltable('/Records/Person'
            passing x
            columns
                id              number path '@id',
                gender          varchar2(64) path 'Gender',
                person_xml$     xmltype path '.'
        )
    ) loop
        dbms_output.put_line(get_id.id);
        dbms_output.put_line(get_id.gender);

        for get_name_type in (
            select *
            from xmltable('Person/NameDetails/Name'
                passing get_id.person_xml$
                columns
                    name_type       nvarchar2(128) path '@NameType',
                    name_values     xmltype path '.'
            )
            order by decode(name_type, 'Primary Name',1, 'Spelling Variation',2, 99) asc
        ) loop
            dbms_output.put_line('--- '||get_name_type.name_type);

            for get_name in (
                select *
                from xmltable('Name/NameValue'
                    passing get_name_type.name_values
                    columns
                        first_name      nvarchar2(128) path 'FirstName',
                        surname         nvarchar2(128) path 'Surname',
                        orig_scr_name   nvarchar2(128) path 'OriginalScriptName'
                )
            ) loop
                dbms_output.put_line(get_name.first_name||' '||get_name.surname||' '||get_name.orig_scr_name);
            end loop;

        end loop;

    end loop;
end;
/