使用FLWOR

时间:2016-10-24 13:05:29

标签: xml oracle11g xquery flwor

我正在尝试删除“number”子元素:     @tsip:形式= “WILA” 使用flwor查询从下面的“应用程序”节点。数据位于Oracle 11g数据库中,在xml_type列中,Oracle使用xquery 1.0。我已经设法在下面完成了这个,但是我的尝试是非常笨拙和冗长的,因为我已经硬编码了父“applications”元素和子“number”元素之间的中间元素,所以如果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:form =“wila”

选择除“number”元素以外的所有数据
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 个答案:

答案 0 :(得分: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)