2016-10-24 2 views
0

flworクエリを使用して、下の "アプリケーション"ノードから @tsip:form = "wila" で "number"子要素を削除しようとしています。データはOracle 11gデータベースにあり、xml_type列にはxquery 1.0が使用されます。私は下でこれを達成することに成功しましたが、親の "applications"要素と子の "number"要素の間に中間要素をコーディングしていたので、私の試みは非常に不器用で長い間巻き込まれていました。動作しない可能性があります。もっと一般的なソリューションを提供できる人は誰ですか?これは、このよりも簡単でなければなりません :FLWORを使用して選択したノードからxml子要素を削除します

は、テーブルを作成します。

CREATE TABLE XML_DOCUMENT_TMP 
(
    DOCUMENT_ID NUMBER(12)      NOT NULL, 
    XML_DATA  SYS.XMLTYPE      NOT NULL, 
    CREATED_DATE TIMESTAMP(6)     NOT NULL 
); 

はXML_DOCUMENT_TMPにいくつかのデータを挿入します。

insert into XML_DOCUMENT_TMP 
(document_id,created_date,xml_data) 
values(6,sysdate,'<patent xmlns="http://schemas.xx.com/ts/20041221/tsip" 
xmlns:tsip="http://schemas.xx.com/ts/20041221/tsip" 
tsip:action="replace" tsip:cc="CA" tsip:se="2715340" tsip:ki="C"> 
<keepThis>data</keepThis> 
<applications tsip:action="new"> 
    <application tsip:cc="GB" tsip:se="2338695" tsip:ki="A" tsip:priorityCode="A2"> 
     <applicationId> 
      <number tsip:form="wila">9813397</number> 
      <number tsip:form="original">9813397</number> 
      <number tsip:form="tsip">000013397</number> 
      <countryCode>GB</countryCode> 
      <applicationYear>1998</applicationYear> 
      <date>1998-06-23</date> 
     </applicationId> 
    </application> 
</applications> 
<keepThis2>data2</keepThis2> 
</patent> 
'); 

は@tsipと "数" の要素以外のすべてのデータを選択します。フォーム= "wila"

SELECT /*+ NO_XML_QUERY_REWRITE */ xA.document_id , 
XMLSerialize(DOCUMENT 
    XMLQuery('xquery version "1.0"; 
     declare default element namespace "http://schemas.xx.com/ts/20041221/tsip"; 
     declare namespace tsip="http://schemas.xx.com/ts/20041221/tsip"; 

     <patent xmlns="http://schemas.xx.com/ts/20041221/tsip" xmlns:tsip="http://schemas.xx.com/ts/20041221/tsip" >{$a/*:patent/@*} 
     { 

     for $s in $a/*:patent/* 
      return 

      if ($s = $a/*:patent/applications) 
      then  
       <applications>{$a/*:patent/applications/@*} 
       <application>{$a/*:patent/applications/application/@*} 
        <applicationId> 
        { 
        (: Use the "except" clause to remove the unwanted <number> element with the "wila" attribute value :) 
        $a/*:patent/applications/application/applicationId/* except $a/*:patent/applications/application/applicationId/number[@tsip:form="wila"] 
        }   
       </applicationId> 
       </application> 
      </applications> 
      else $s 
     } 
     </patent>' 
      PASSING xA.xml_data as "a" 
      RETURNING CONTENT)) newXml 
FROM XML_DOCUMENT_TMP xA    
WHERE document_id=6; 

答えて

1

XQueryでは、再帰関数各ノードにアクセスしてそのノードを削除する必要があるかどうかをテストします。それは削除する必要がある場合は、あなたが何もしない、それは削除すべきでない場合は、同じ名前element {node-name(.)} { ...を持つ新しいノードとして、それのコピーを作成し、その子を訪問し続ける。そのため

declare namespace tsip="http://schemas.xx.com/ts/20041221/tsip"; 
declare function local:transform($root) { 
    $root/(typeswitch (.) 
    case element(tsip:number) return 
    if (@tsip:form = "wila") then() 
    else . 
    case element() return 
     element {node-name(.)} { 
     @*, for $n in node() return local:transform($n) 
     } 
    default return . 
) 
}; 
local:transform($a) 
+0

おかげで、それは」doesnの"wila"属性を持つnumber要素を削除しているようですか? –

+0

さて、それはすべきです。たぶん '$ a'が単なる要素ではなく、文書でない限り。その場合、最後の行で '$ a/*'を試してください。 – BeniBela

+0

それはありがたいことです。私は新しい関数の再帰関数がありましたが、再帰関数が嫌いです。 –

関連する問題