[英]Delete a xml child element from a selected node using FLWOR
I'm trying to remove the "number" child element with: @tsip:form="wila" from the "applications" node below using a flwor query. 我正在尝试使用flwor查询从以下“应用程序”节点中删除@number子元素:@tsip:form =“ wila”。 The data is in an Oracle 11g database, in a xml_type column, Oracle uses xquery 1.0.
数据位于Oracle 11g数据库的xml_type列中,Oracle使用xquery 1.0。 I've managed to accomplish this below but my attempt is very clumsy and long winded as I have hard coded the intermediate elements between the parent "applications" element and the child "number" element , so if the format of the xml changes my query may not work.
我已经设法在下面完成此操作,但是由于我已经硬编码了父“应用程序”元素和子“数字”元素之间的中间元素,因此我的尝试非常笨拙且漫长,所以如果xml的格式更改了我的查询,可能不起作用。 Can anyone offer a more generic solution.
任何人都可以提供更通用的解决方案。 It must be easier than this:
它一定比这更容易:
Create a table: 创建一个表:
CREATE TABLE XML_DOCUMENT_TMP
(
DOCUMENT_ID NUMBER(12) NOT NULL,
XML_DATA SYS.XMLTYPE NOT NULL,
CREATED_DATE TIMESTAMP(6) NOT NULL
);
Insert some data into XML_DOCUMENT_TMP: 将一些数据插入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>
');
Select all the data except the "number" element with @tsip:form="wila" 使用@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;
In XQuery you can use a recursive function to visit each node and test if that node should be removed. 在XQuery中,您可以使用递归函数访问每个节点并测试是否应删除该节点。 If it should be removed, you do nothing, if it should not be removed you make a copy of it as a new node with the same name
element {node-name(.)} { ...
and continue visiting its children: 如果应删除它,则不执行任何操作,如果不删除它,则将其复制为具有相同名称
element {node-name(.)} { ...
的新节点,然后继续访问其子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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.